Static typing ain't so bad, after all...

  • Thread starter Just Another Victim of the Ambient Morality
  • Start date
C

Chad Perrin

...but this is often not enough. What if the parameter is called
"node."

That doesn't even address the exhortation to name your functions
properly, because "node" is a terrible name for a function unless the
operation of your program is so clearly defined and its requirements and
context so obvious that "node" becomes an explicit description of
functionality. Even then, it's probably not as expressive as it could
be.
 
J

Just Another Victim of the Ambient Morality

i think that's a silly thing to say. straight away, tell me what role
this
function plays:

void (*signal(volatile int x, void (*const y)(int )))(int );

??

and i don't think that's being unfair. the reason is that static typing
builds up mountains of information for even mildly complex function
definitions. there is a reason a program exists (cdecl) to decode them!
it's
very existence backs my assertion that little can be groked 'staight
away'
merely by statically/explicitly typing function signatures.

You're right. I did make a blanket statement about statically typed
languages that's not always true. However, it does often help to know what
types are being used when reading a function definition. Consider this
example:


def parse data, machine
node = data.index 0
machine.process node
end


As it is now, it's rather contrived but you could add some
(contextually) sensible code around it without disturbing this basic
functionality and see it offers no clue as to what "node" or "machine" is.
You could look for anything with a "process" method but what "node" will be
is much harder to find and important to the understanding of what this
method is for (despite that it's obviously not important to understanding
what the method actually does).

in addition, languages like ocaml, while also statically typed, leave
this
information out of the source while still be readable:

let double x = x * 2;;

let sum x y = x + y;;

let factorial x =
if (0 > x) then (raise Exit) else
match x with
0 -> 1
| n -> (n * (factorial (n - 1)));;


notice - this is statically typed. also notice the lack of explicitly
encoded
typing - the compiler figures it out.

You're right. I'm talking more about explicit typing rather than
"static typing," so perhaps my thread is ill named...

so, to drive it home further, you seem to think 'static' means
'explicitly
written by the programmer' - but of course that's not what it means.
fortunately, the 'explicit' route is available to you in ruby by simply
following certain pratices, either comment functions or cast arguments
using
the 'class name as casting ctor pattern' used all over the place in ruby.
for
isntance

def m a, b, c
a = String a
b = Integer b
c = Float f

....
end

now, that's not static, but it is explicit. you can obivously follow
this
pattern with user defined classes.

I may but others may not. I am looking over code that does not follow
this convention (nor did I expect them to) so it doesn't help my
situation...

templates are not dynamic typing though - i'd say they are testimony to
how
much of a bastard a strong/static/non-inferred type system can be and how
adding compiler features to do the work for us is essential. note that
templates and any other sort of compiler inference feature __remove__
explicit
type info from the source!

...but they perform the same purpose.
The purpose of C++ templates is to reuse code. Often, you want to
perform the same operations on different types of data. A linked list of
integers doesn't behave any differently than a linked list of strings,
except that one has integers while the other has strings.
The purpose of dynamic typing, as far as I can tell, is to reuse code.
Sure, you can reuse a variable for very different purposes but is that
really such an advantage? In my opinion, the purpose of dynamic typing is
so that methods can accept parameters of varying types and perform the same
operations on those types, thus reusing the method code...

correct - you'd simply have different ones.

Of course... What do you think I'm trying to say here? That static
typing is the way to go and Ruby should adopt it? You can't probably think
that after everything else I've said so it must be something else...
I'm looking to see how people deal with the problems that come up from
being dynamically typed...

well, i showed one solution above. there are plenty of others.

Well, I can't wait to hear them!
 
J

Just Another Victim of the Ambient Morality

Chad Perrin said:
That doesn't even address the exhortation to name your functions
properly, because "node" is a terrible name for a function unless the
operation of your program is so clearly defined and its requirements and
context so obvious that "node" becomes an explicit description of
functionality. Even then, it's probably not as expressive as it could
be.

You know, it looks like you trimmed off the context and then responded
that, rather than reading the post and then trimming off the unimportant
parts in your response.

In my example, "node" is a parameter and an object, not a method name.
It's curt but it's not entirely a bad name, as long as it is a node of
something that has nodes. It could be more expressive but just as my
example demonstrated (the context that you trimmed in your response), it's
hard to expand on it. You could say what type of structure it is a node
for but that doesn't help that much unless you're intimately familiar with
that structure. In my case, what would really have helped is if I can find
the definition of one of these nodes that will be passed in (so that I may
become intimately familiar with that structure). In my case, I think there
is only one type that will ever be passed into this function but, of
course, that's hard to tell...
 
A

ara.t.howard

You're right. I did make a blanket statement about statically typed
languages that's not always true. However, it does often help to know
what types are being used when reading a function definition. Consider
this example:


def parse data, machine
node = data.index 0
machine.process node
end


As it is now, it's rather contrived but you could add some (contextually)
sensible code around it without disturbing this basic functionality and
see it offers no clue as to what "node" or "machine" is. You could look
for anything with a "process" method but what "node" will be is much
harder to find and important to the understanding of what this method is
for (despite that it's obviously not important to understanding what the
method actually does).

fair enough. i don't disagree here that explicit typing might __help__ here,
but it's only one tool when statically analyzing code.

You're right. I'm talking more about explicit typing rather than "static
typing," so perhaps my thread is ill named...
ok.

I may but others may not. I am looking over code that does not follow
this convention (nor did I expect them to) so it doesn't help my
situation...
granted.

...but they perform the same purpose. The purpose of C++ templates is to
reuse code. Often, you want to perform the same operations on different
types of data. A linked list of integers doesn't behave any differently
than a linked list of strings, except that one has integers while the
other has strings. The purpose of dynamic typing, as far as I can tell,
is to reuse code. Sure, you can reuse a variable for very different
purposes but is that really such an advantage? In my opinion, the
purpose of dynamic typing is so that methods can accept parameters of
varying types and perform the same operations on those types, thus
reusing the method code...

hmmm. i see the primary advantage of dynamic typing as the time saving i gain
by not spoon feeding the compiler and the associated productivity gain. you
are pointing out that it does not always save time, but my experience is that
it does for a large percentage of the time.
Of course... What do you think I'm trying to say here? That static
typing is the way to go and Ruby should adopt it? You can't probably
think that after everything else I've said so it must be something
else... I'm looking to see how people deal with the problems that come
up from being dynamically typed...

i understand. still, these static/dynamic threads often get muddled by ill
definitions and then ramble forever - it's best to get on the same page
regarding terms and the problem... that's all.
Well, I can't wait to hear them!

i guess what i'd offer is that mechanisms like

- explicit typing
- documentation
- introspection (as in runtime debugging)
- static typing
- clear coding conventions

all contribute to code understanding and that many of these features are
available to ruby and not, for example, c and vise-versa. if someone leaves
you with no tools then it's just bad code! ;-)

in this case it seems nearly so but you do still have rtti under irb/debug
mode. it's a powerful tool if not easy to get setup with an appropriate
env...

kind regards.

-a
 
C

Chad Perrin

You know, it looks like you trimmed off the context and then responded
that, rather than reading the post and then trimming off the unimportant
parts in your response.

I just didn't want to swim through code -- which is sorta the point of
good naming conventions: not having to reason through an entire
program's logic to figure out what something does. I see something
called "node" and think "What the hell does THAT mean?" then start
wondering whether I have to read through, and flowchart, the entire
program to figure it out.
 
L

Leslie Viljoen

In my example, "node" is a parameter and an object, not a method name.
It's curt but it's not entirely a bad name, as long as it is a node of
something that has nodes. It could be more expressive but just as my
example demonstrated (the context that you trimmed in your response), it's
hard to expand on it. You could say what type of structure it is a node
for but that doesn't help that much unless you're intimately familiar with
that structure. In my case, what would really have helped is if I can find
the definition of one of these nodes that will be passed in (so that I may
become intimately familiar with that structure). In my case, I think there
is only one type that will ever be passed into this function but, of
course, that's hard to tell...

Almost anyone can write hard to understand code in any language - I
try to comment anything that might be unclear in the code I'm writing.
Particularly I maintain a lot of C# code where arb names are invented
for objects, making it hard to guess their function.

But you are right that it's normally easy to determine the structure
of objects passed to functions in C# - normally as easy as
"right-click->go to definition". Since most of my Ruby functions get
called with only certain objects as parameters, I wonder if a clever
text search wouldn't be able to guess at those objects. Of course,
just looking at the function it would be impossible to tell, but a
clever search might be able to see:


def PrintMarks(marks)

has been called only by:
PrintMarks(marks)

and above that is:

marks = markSheet[0]

and somewhere before that is:

markSheet[0] = StudentMarkTable.new

etc.

Of course it might not be worth the effort to write such a thing, I
have certainly not needed it badly enough.

Les
 
J

Just Another Victim of the Ambient Morality

hmmm. i see the primary advantage of dynamic typing as the time saving i
gain
by not spoon feeding the compiler and the associated productivity gain.
you
are pointing out that it does not always save time, but my experience is
that
it does for a large percentage of the time.

Personally, I don't see these small "time savings" as a big advantage.
Perhaps I shouldn't shrug off "syntactic sugar" so easily but features of a
language that save a bit of typing aren't a big deal to me. I'm a fast
typist and software is plagued by so many other issues...
Please don't misunderstand me. Ultimtely, all features of a language
are "time saving" ones, in that we obviously want to spend as little time
as possible to get the job done. However, since I spend most of my time
thinking about how to do things and figuring out why my implementation
doesn't work (debugging) and very little time actually typing out my
program, I prefer some of the more macroscopic features of a language. For
C++, that would be templates (the STL and boost), typing and subtyping.
For Ruby, that would be dynamic typing (which replaces the whole C++
template idea), blocks as closures and it's general run-time flexability
(the fact that attr_accessor can be defined in the language itself is
amazing!)...
This may explain why I use other people's code so much. I'd rather not
waste time re-inventing the wheel and will gladly borrow one from someone
else...

i guess what i'd offer is that mechanisms like

- explicit typing
- documentation
- introspection (as in runtime debugging)
- static typing
- clear coding conventions

all contribute to code understanding and that many of these features are
available to ruby and not, for example, c and vise-versa. if someone
leaves
you with no tools then it's just bad code! ;-)

Yeah, I'm not surprised that this might be one of those "what can you
do? Life is hard..." problems. I was just throwing this out there in case
it was interesting and that, maybe, someone might have a surprising
solution or approach to this issue...

Incidentally, what inspired all this is that I'm trying to use
mechanize and it's totally not working. Specifically, some sites like
slashdot.org work fine but rubyforge.org fails spectacularly. What happens
is that all links at rubyforge.org are nil. Some debugging suggests that
the problem is in htmltools, which mechanize uses to parse the HTML. So,
someone else's code uses someone else's code to do the work. Now you can
see why the term "node" comes up a lot in my example problems.
Except for the copyright and license agreement, there's almost no
documentation...
I'm tempted to make another post asking other people who use mechanize
(and/or htmltools) to go to rubyforge.org and see if they have the same
problems I do...
 
A

ara.t.howard

Personally, I don't see these small "time savings" as a big advantage.
Perhaps I shouldn't shrug off "syntactic sugar" so easily but features of
a language that save a bit of typing aren't a big deal to me. I'm a fast
typist and software is plagued by so many other issues...

ah. just to clarify i meant that the reduction in total lines of code is a
huge boon for me, not only when writing code, but more importantly when
__reading__ it later. no amount of static typing helps with 10,000 line
fortran files, for instance, and i maintain a lot of code.
Yeah, I'm not surprised that this might be one of those "what can you do?
Life is hard..." problems. I was just throwing this out there in case it
was interesting and that, maybe, someone might have a surprising solution
or approach to this issue...

Incidentally, what inspired all this is that I'm trying to use mechanize
and it's totally not working. Specifically, some sites like slashdot.org
work fine but rubyforge.org fails spectacularly. What happens is that
all links at rubyforge.org are nil. Some debugging suggests that the
problem is in htmltools, which mechanize uses to parse the HTML. So,
someone else's code uses someone else's code to do the work. Now you can
see why the term "node" comes up a lot in my example problems.
Except for the copyright and license agreement, there's almost no
documentation...
I'm tempted to make another post asking other people who use mechanize
(and/or htmltools) to go to rubyforge.org and see if they have the same
problems I do...

this seems like a good fit for ruby-breakpoint.

gem install ruby-breakpoint

it's great for debugging these kinds of things via introspection - just throw
in a breakpoint and start inspecting live code.

on a related note - curl and wget sure work good ;-)

good luck!

-a
 
I

Isaac Gouy

Just said:
-snip-

Yeah, I'm not surprised that this might be one of those "what can you
do? Life is hard..." problems. I was just throwing this out there in case
it was interesting and that, maybe, someone might have a surprising
solution or approach to this issue...

Another mechanism - IDE support.

The most basic Smalltalk code exploration builds on tools for browsing
implementors/senders of methods. We'd browse all implementors of "parse
data, machine" to see if we were dealing with a massively polymorphic
method, and then we'd browse all senders of "parse data, machine" and
keep tracing back to see what sort of things "data.index 0" was being
initialized with.
 
J

Jeremy Henty

For preventing the problem, my answer is the same as everyone
else's... Good naming techniques.

Word! I still remember the time I found a bug in my code simply by
renaming a poorly-named method. As soon as I saw the result of the
replacement I thought "Hold on, that's wrong!".

Jeremy Henty
 
J

Jeremy Henty

As for static typing... I feel your pain. It's heresy, but I
prefer static typing.

You'll come round! I did, and I was a hard-core ML/Haskell lover.
They all crack in the end! ;-)

Jeremy Henty
 
J

Justin Collins

Leslie said:
In my example, "node" is a parameter and an object, not a method
name.
It's curt but it's not entirely a bad name, as long as it is a node of
something that has nodes. It could be more expressive but just as my
example demonstrated (the context that you trimmed in your response),
it's
hard to expand on it. You could say what type of structure it is a node
for but that doesn't help that much unless you're intimately familiar
with
that structure. In my case, what would really have helped is if I
can find
the definition of one of these nodes that will be passed in (so that
I may
become intimately familiar with that structure). In my case, I think
there
is only one type that will ever be passed into this function but, of
course, that's hard to tell...

Almost anyone can write hard to understand code in any language - I
try to comment anything that might be unclear in the code I'm writing.
Particularly I maintain a lot of C# code where arb names are invented
for objects, making it hard to guess their function.

But you are right that it's normally easy to determine the structure
of objects passed to functions in C# - normally as easy as
"right-click->go to definition". Since most of my Ruby functions get
called with only certain objects as parameters, I wonder if a clever
text search wouldn't be able to guess at those objects. Of course,
just looking at the function it would be impossible to tell, but a
clever search might be able to see:


def PrintMarks(marks)

has been called only by:
PrintMarks(marks)

and above that is:

marks = markSheet[0]

and somewhere before that is:

markSheet[0] = StudentMarkTable.new

etc.

Of course it might not be worth the effort to write such a thing, I
have certainly not needed it badly enough.

Les

But it kinda sounds like a fun project...hmmmmmm....

-Justin
 
D

David Vallner

Isaac said:
Another mechanism - IDE support.

The most basic Smalltalk code exploration builds on tools for browsing
implementors/senders of methods. We'd browse all implementors of "parse
data, machine" to see if we were dealing with a massively polymorphic
method, and then we'd browse all senders of "parse data, machine" and
keep tracing back to see what sort of things "data.index 0" was being
initialized with.

Type information being part of the method signatures usually helps
narrow this down. I sort of get where HorkingLongAndObnoxiousName is
coming from - "parse" is a very generic method name and might be found
around the system with even the same arity for wildly varying purposes.
Without as much as receiver type information, the code search could show
a lot of unrelated results.

Hopefully, you could further narrow them down by making assumptions
based on identifier names, but that's a) error-prone, and b) better not
to have to do by hand.

Making sophisticated tool support is much easier if the tools have much
more information at their disposal, and statically typed code does
provide more / easier machine-analysable information.

Dynamic typing is inherently more prone to being hard to maintain. The
problems can be very well mitigated using proper conventions, and common
sense.

But that's not always the case, and when you get thrown on a project as
a maintainer or to contribute feature XY into revision Z of a codebase
that had random people without a code style guide leading them working
on it for two years, you get very, very happy that you have Ctrl-Shift-G
in Eclipse on your side. In a rainy day scenario, the systems aren't
quite equivalent.

David Vallner
 
D

David Vallner

Also, please -- PLEASE -- read the hundreds, or perhaps thousands, of
posts about this in the ruby-talk archives. I'm not optimistic about
breaking the cycle; it seems we're doomed to have this thread repeated
three or four times a year. But, I don't know, maybe one of these
years we can stop.

Here, take a "PWNT3HN00BS!" T-shirt. Brought to you by the Grumpy Jaded
Gits Anonymous.

The best strategy is to take two painkillers, wait for the caffeine to
wear off, and then start copy/pasting the explanations.
MustExpandYourEmailClientsAdressColumnToThreeTimesItsUsualSize is
obviously a tad bit new, so you can either start making scary
hand-motions in hopes he runs for the hills, or join the crowd in
showing him The Light. I actually find that strangely soothing - gives
me that fuzzy feeling all over when someone Gets It.

*wombles back to proselytizing*

David Vallner
 
D

David Vallner

Sure, you can reuse a variable for very different purposes but is that
really such an advantage?

You don't do this. Heck, you shouldn't even reuse a variable for the
same purpose. Reusing variables tends to imply that you don't really
know what their purpose was in the first place.

The advantage of dynamic typing comes in working with the hairier design
patterns. It's a reduction ad extremum of a way of constraining object
behaviour - the typical members of the "expliticly" typed language group
use type / class hierarchies for this, and check against those.

The group of dynamically typed languages doesn't make assumptions based
on the elements that make up an object's behaviour belonging together -
an object is of the correct type for a given message send if it responds
to said one message, nothing more, nothing less.

For (a very contrived) example any object that just so happens to
properly respond to the messages for arithmethical operations can be
substituted for an "integer" you only ever do arithmetics with without
the language runtime batting an eyelash.

In dynamically typed languages, the type of an object isn't its "class"
or any other predictable concept, it's just the protocol it adheres to
during its lifetime. Most such languages also make no presumption that
this protocol, or the behaviour of an object remains the same during its
lifetime - which makes compile-time checks rather pointless.

Of course, you rarely use even this aspect of dynamic typing - in fact,
I can't come up with a single noncontrived example for it, these things
just don't occur in daily coding. But dynamic languages sure a heck
faster to type, and the fact the compiler rarely bitches at all is very,
very appealing to people that know what they're doing most of the time.

David Vallner
 
C

Chad Perrin

MustExpandYourEmailClientsAdressColumnToThreeTimesItsUsualSize is

On that note . . .

I'd really like to see subject lines get shorter than they have been
lately, on a number of threads. What good is a subject line so long
that you can't see half of it displayed in your MUA?
 
D

David Vallner

William said:
As for static typing... I feel your pain. It's heresy, but I prefer
static typing. Inheritance provides everything I need that Duck Typing
does for me. (At least, so far. I'm really new to Ruby.)

Static typing has limitations where dynamic typing doesn't have them,
but they're really few and far between. Doing proof-of-concept code, or
exploring more exotic design patterns come to mind. Horses for courses,
I presume, I'm in the "add optional type / interface / protocol
adherence checks" camp myself.
-sigh- Victim, your name triggers the spam filter here. Am I the only
one annoyed by this?

Har. So far, only the spam filters in my head go off. Reminds me of my
little sister's 12 year old IM friends that whap arbitrary deep-sounding
fluff into their screen names.

David Vallner
 
C

Chad Perrin

That was a perceptive comment. The fact that there are so few true cases of
objects that metamorphose in flight also accounts for the observed "magical"
behavior that "duck-typing" seems to "just work" almost all of the time. (By
magical, I mean unexpected for people like me with too many years of
experience programming in statically-typed languages.) The intention of a
well thought-out code path is generally easy to express without typing all
the types along the way. It doesn't break often, and when it does break, it
doesn't make a big mess.

I think much of the reason for difficulty enumerating common-case
benefits derived from dynamic typing is the simple fact that dynamic
typing makes other language features possible, or at least (easily)
usable, that would otherwise be prohibitively difficult to implement.
In other words, duck typing works silently behind the scenes most of the
time, providing the foundation for other, more direct benefits, but
doesn't jump up in your face taking credit for stuff.
 
J

Just Another Victim of the Ambient Morality

David Vallner said:
You don't do this. Heck, you shouldn't even reuse a variable for the same
purpose. Reusing variables tends to imply that you don't really know what
their purpose was in the first place.

I don't think we disagree here. This is one thing that dynamic typing
allows you to do and I'm questioning whether this is a benefit and you're
saying it absolutely isn't. So, we can agree that this does not contribute
to the benefits of dynamic typing...

The advantage of dynamic typing comes in working with the hairier design
patterns. It's a reduction ad extremum of a way of constraining object
behaviour - the typical members of the "expliticly" typed language group
use type / class hierarchies for this, and check against those.

By "it's a reduction ad extremum of a way of constraining object
behaviour" do you mean that it reduces object behaviour in an extremely
non-constraining way?
With statically typed languages, the behaviour of an object is defined
by membership. If this variable is a member of this set, then it may have
these properties. So, when a function requires that a parameter be of a
certain type, it must be a member of this certain set. The use of other
types that may also work in this function but are not in this set are
(arbitrarily) excluded.
With dynamically typed langauges, because variables (including
parameters) may be of any type, parameters passed into a method will work
as long as they, literally, satisfy the requirements of the method. This
is much more flexable than defining arbitrary membership. It's "ad
extremum" in the direction of flexability. Unfortunately, it's also
flexable enough to allow you to pass a totally inappropriate parameter into
a method but that's the trade off. Is it worth it? Most of us think so...

In my opinion, this amounts to promoting the use of code in differing
contexts (or, simply, code reuse), which is the advantage that I had stated
before...

For (a very contrived) example any object that just so happens to
properly respond to the messages for arithmethical operations can be
substituted for an "integer" you only ever do arithmetics with without
the language runtime batting an eyelash.

This isn't a contrived example, it's just a vague one.
If you want an example you can use in the future, how about a function
or method that takes a vector and a list of vectors and sees if the given
vector can be expressed as a linear combination of the list of vectors.
Because so many things have vector properties (real numbers, complex
numbers, Cartesian vectors, matrices, real valued functions, almost
anything, it seems), you can reuse this function or method with any of
these types! How amazing is that?
 
D

David Vallner

Just said:
By "it's a reduction ad extremum of a way of constraining object
behaviour" do you mean that it reduces object behaviour in an extremely
non-constraining way?

Yes. In the object-message interpretation of OO, it means an object only
needs to respond to the messages absolutely required in a context to be
qualified to be of the valid type.
With statically typed languages, the behaviour of an object is defined
by membership. If this variable is a member of this set, then it may have
these properties. So, when a function requires that a parameter be of a
certain type, it must be a member of this certain set. The use of other
types that may also work in this function but are not in this set are
(arbitrarily) excluded.
With dynamically typed langauges, because variables (including
parameters) may be of any type, parameters passed into a method will work
as long as they, literally, satisfy the requirements of the method. This
is much more flexable than defining arbitrary membership. It's "ad
extremum" in the direction of flexability. Unfortunately, it's also
flexable enough to allow you to pass a totally inappropriate parameter into
a method but that's the trade off. Is it worth it? Most of us think so...

<pedant>
*flexibility
</pedant>

As Chad Perrin pointed out, you leverage the benefits of dynamic typing
in the special / edge cases rather than the common case. If you poked
around Ruby libraries, you'd find out at least several, if not many
cases when the libraries perform strong type checks on objects passed
into them.

And for what it's worth, I personally don't see a problem with this. It
makes the libraries easier to document, easier to understand, and behave
more predictably. Ruby -allows- you to use (and abuse) dynamic typing,
noone's saying you need to code to allow for it. I would personally
advocate the opposite, write predictable code most of the time, and then
do parts of it that could benefit from the dynamism by design - since
they will be inherently more error-prone, they require a lot more effort
to be written in a robust maintainable way.
If you want an example you can use in the future, how about a function
or method that takes a vector and a list of vectors and sees if the given
vector can be expressed as a linear combination of the list of vectors.
Because so many things have vector properties (real numbers, complex
numbers, Cartesian vectors, matrices, real valued functions, almost
anything, it seems), you can reuse this function or method with any of
these types! How amazing is that?

Interesting example there. Of course, I'd personally formalise the
vector properties somehow, at least in documentation. You want these
vector properties to manifest themselves in the different types of
objects in a consistent way, and this is a constraint on the parameters
of the function already. And in good-quality code, you want to check on
whether the constraint is satisfied and fail early if it doesn't.

Even dynamic / duck typing isn't completely eschewing type checks, even
if you can get away with that for spectacularly long. And the problem is
that expressing the parameter constraint with "is a Vector" is a little
clearer than "has vector properties". It's not -that- apparent in this
example, but for more complex ones, where you need a larger set of
behaviours from the function parameters, the formal granular constraints
on them would be very verbose and hard to understand. Having "ubmrella"
concepts that are readily understood is very helpful in that case. And
the path between concept and code is sometimes a very short one - having
a mixin Vector module with documented methods that you expect from an
object "with vector properties" and some helper methods you'd use would
probably be my first move after making a vector manipulation library
with the dynamism you describe.

David Vallner
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top