Thoughts on typelessness

I don’t know, Alan; just like Java, probably some typing is currently the
only obvious way to make Ruby run even faster, but people are saying that
it is not the Ruby way. If there is indeed a new technology that can make
Ruby run faster without some typing, that will indeed be the right way to
go.

My whole point was that you might want to consider exploring
optimizations with ruby as is. Optimizations may be more difficult,
but they are certainly possible. When you have application running a
ruby codebase, an optimizing ruby engine (ORE?). In many cases,
parameters passed to function and method calls will be primarily of
the same type. Say function foo(x). In the codebase, maybe x is never
anything but an Array. ORE then creates a block of optimized machine
code assuming x is an array with some detection logic to fallback to
the regular code if x is not an array. Maybe ORE has a “profile” mode,
builds up some run profiling data and them builds the optimized machine
code based on the profile. Or the programmer looks over the profile data
and picks which functions with what type signature to build optimized
code for – all while keeping the Ruby language largely intact, and not
intruducing static typing to function prototypes.

In my dream language, the typing is optional, and then I will add ‘struct’
(not the current Ruby Struct), so that member data “@data” is not accessed
through hash anymore, but through memory offset. It will take me some
time to learn lex and yacc and the Ruby interpreter. As already
commented, probably eventually I will have to take the task myself (if I
have the time).

I think that implementing offset based struct would be a good introduction
to the Ruby-C interface.

···

On Wed, Oct 02, 2002 at 08:01:04AM +0900, William Djaja Tjokroaminata wrote:


Alan Chen
Digikata LLC
http://digikata.com

William, what about this?

def func (a)
a.is_a?(Fixnum) or raise “type error”

As someone that is reading someone else’s source, that is what I’d be
grateful for. It’s almost plain English and makes your intent very
clear.

Massimiliano

···

On Tue, Oct 01, 2002 at 10:39:55PM +0900, William Djaja Tjokroaminata wrote:

I usually code

def func (a)
    raise "type error" unless a.kind_of? Fixnum
    ....

Now, I just want a convenience in writing the above code if I can just
write

def func (Fixnum a)
    ....

In this case, that’s it. The new code is not more safe than the code that
we can write right now with Ruby. It is just more convenient, I
guess…

Hello Dave,

Tuesday, October 01, 2002, 6:00:35 PM, you wrote:

For me, it is because I assume that my code user (sometimes including
myself) will make mistakes, such as giving the code a String when a Fixnum
is expected. Therefore, so that I can catch the error as early as
possible (to give more useful hints to the user that it is his/her input
that is wrong, not the code), I usually code

def func (a)
    raise "type error" unless a.kind_of? Fixnum
    ....

Ruby types are not releated to classes. They’re related to object
protocols (the infamous Duck Typing). That’s what gives Ruby much of
its appeal. Testing for classes is really very poor style, and
artificially constrains the users of your code.

there is tradeoff between flexibility and reliability. especially for
such types as Fixnum :wink: which has never to be emulated by some other
class

···


Best regards,
Bulat mailto:bulatz@integ.ru

Hello Albert,

Tuesday, October 01, 2002, 6:01:11 PM, you wrote:

Hi, Bill. You are very persistent and seem to be a little slow on the uptake.
In that I already have a reputation on this list as being somewhat of a loose
cannon, let me state something very clearly. Type checking is undesired and
unnecessary in any purely OOP language, Ruby included.

eiffel too? :slight_smile: untyped variables is common for
interpreted/script/prototype languages, not OO langs

···


Best regards,
Bulat mailto:bulatz@integ.ru

Hi Albert,

Totally agree. As in one of my previous posts, I will do the “shortcut
convenience” myself when the time is available (I don’t think it is
difficult at all).

Regarding recruiting, well, I don’t know; but when someone else posts a
similar idea, I immediately throw my support… (recruiting, supporting?)

Regards,

Bill

···

=============================================================================
Albert Wagner alwagner@tcac.net wrote:

You seem to be intent
on recruiting someone else to write a new language to your specifications. I
suspect that you will not find anyone willing to do that here. Therefore, I
suggest that you take what is the time honored path in open source software:
do it yourself.

Hi Dave,

I think in my application it is probably enough to check for classes. For
example, my abstract factory pattern function to create a communications
network link is:

def link (node0, node1, rate = 1e6, delay = 0.0, model = nil, attrs = nil,
type = Link::TYPE_FULL_DUPLEX, label = ‘’, name = ‘’, simStart = false,
simEnd = false, sim = nil)
raise “…” unless rate.kind_of? Float
raise “…” unless delay.kind_of? Float

end

Really, I want the ‘rate’ and ‘delay’ to be of class Float and nothing
else. There are so many input parameters, because to me they are all
essential in creating a link. So when a researcher uses my code and
he/she just mistakenly skips one parameter, if the code omits some
confusing syntax error, the researcher may immediately think, “Oh,
what a buggy code”. But if the error message is something like “input
error in method ‘link’: ‘rate’ should be of type Float, method called
from line…”, I think he/she will simply just immediately correct his/her
input. (I know this does not handle all possible kinds of input errors,
such as negative number, but for now probably some checking is better than
no checking at all, because it at least helps me better. When (and
if) the GUI is developed in the future, then it will be full-blown error
checking.)

Can you provide some idea on how to better deal with user input error
using probably some Ruby paradigm?

Regards,

Bill

···

============================================================================
Dave Thomas Dave@pragmaticprogrammer.com wrote:

Ruby types are not releated to classes. They’re related to object
protocols (the infamous Duck Typing). That’s what gives Ruby much of
its appeal. Testing for classes is really very poor style, and
artificially constrains the users of your code.

William Djaja Tjokroaminata billtj@y.glue.umd.edu writes:

Hi,

For me, it is because I assume that my code user (sometimes including
myself) will make mistakes, such as giving the code a String when a
Fixnum
is expected. Therefore, so that I can catch the error as early as
possible (to give more useful hints to the user that it is his/her input
that is wrong, not the code), I usually code

def func (a)
    raise "type error" unless a.kind_of? Fixnum
    ....

Ruby types are not releated to classes. They’re related to object
protocols (the infamous Duck Typing). That’s what gives Ruby much of
its appeal. Testing for classes is really very poor style, and
artificially constrains the users of your code.

How universal is this terminology, especially
in Rubyland? After all, isn’t #class basically
a synonym for #type?

Hal

···

----- Original Message -----
From: “Dave Thomas” Dave@PragmaticProgrammer.com
To: “ruby-talk ML” ruby-talk@ruby-lang.org
Sent: Tuesday, October 01, 2002 9:00 AM
Subject: Re: thoughts on typelessness

Hi Alan,

All your idea below seems good, but has anything like that been done
before, in some other languages, perhaps?

Let me also try to understand further your idea. Basically, are you
saying that the type of the object referred to by a variable seldom
changes? In this case I agree. So instead of using explicit typing on
the variable itself, let the computer assigns the type to the variable
based on the runtime type of the object referred to by the variable. Am I
correct?

As I got the impression that Dylan has both static and dynamic typing, I
will also scan the language.

Regards,

Bill

···

============================================================================
Alan Chen alan@digikata.com wrote:

My whole point was that you might want to consider exploring
optimizations with ruby as is. Optimizations may be more difficult,
but they are certainly possible. When you have application running a
ruby codebase, an optimizing ruby engine (ORE?). In many cases,
parameters passed to function and method calls will be primarily of
the same type. Say function foo(x). In the codebase, maybe x is never
anything but an Array. ORE then creates a block of optimized machine
code assuming x is an array with some detection logic to fallback to
the regular code if x is not an array. Maybe ORE has a “profile” mode,
builds up some run profiling data and them builds the optimized machine
code based on the profile. Or the programmer looks over the profile data
and picks which functions with what type signature to build optimized
code for – all while keeping the Ruby language largely intact, and not
intruducing static typing to function prototypes.

I can see how type checks like the above would be restrictive,
but I can’t find anything about “Duck Typing” on Google.

I did find a couple references to Matz talking about Dave Thomas
talking about Duck Typing.

Then there’s a reference to Donald Duck, typing. (Maybe this is
what Mr. Thomas is talking about?)

Any help would be appreciated.

  • Ryan King
···

On 2002.10.01, Dave Thomas Dave@PragmaticProgrammer.com wrote:

def func (a)
    raise "type error" unless a.kind_of? Fixnum
    ....

Ruby types are not releated to classes. They’re related to object
protocols (the infamous Duck Typing). That’s what gives Ruby much of
its appeal. Testing for classes is really very poor style, and
artificially constrains the users of your code.

William Djaja Tjokroaminata billtj@y.glue.umd.edu writes:

Really, I want the ‘rate’ and ‘delay’ to be of class Float and nothing
else.

Can you provide some idea on how to better deal with user input error
using probably some Ruby paradigm?

Perhaps:

def my_method(rate, delay, ...)
  wibble(rate.to_f, delay.to_f, ....)

Here you’re not insisting that ‘rate’ and ‘delay’ are floats, but
instead that they can yield float values: that they can behave as
floats.

Cheers

Dave

Not that this discussion is about refactoring…but…

You could restructure this a bit and use a Hash instead of all those
params.

Just having to know the order of so many params is a nightmare.

LINK_DEFAULTS = {:rate => 1e6,
:delay => 0.0,
:type => Link::TYPE_FULL_DUPLEX,
:label => ‘’,
:name => ‘’,
:simStart => false,
:simEnd => false
}

def link(node0, node1, map={})
LINK_DEFAULTS.each do |key, value|
map[key]=value unless map.has_key?(key)
unless map[key].kind_of? value.class
raise “Invalid parameter type #{key} must be a #{value.class}”
end
end
…do whatever you want with values
end

usage:

link(n1, n2, :name=>‘wiggy’, :simEnd=>true)

Oh…and the unless map…thingy checks all the types based on the
defaults :wink:

Just my $.02,

-rich

···

-----Original Message-----
From: William Djaja Tjokroaminata [mailto:billtj@y.glue.umd.edu]
Sent: Tuesday, October 01, 2002 11:00 AM
To: ruby-talk ML
Subject: Re: thoughts on typelessness

Hi Dave,

I think in my application it is probably enough to check for
classes. For example, my abstract factory pattern function
to create a communications network link is:

def link (node0, node1, rate = 1e6, delay = 0.0, model = nil,
attrs = nil, type = Link::TYPE_FULL_DUPLEX, label = ‘’, name
= ‘’, simStart = false, simEnd = false, sim = nil)
raise “…” unless rate.kind_of? Float
raise “…” unless delay.kind_of? Float

end

Really, I want the ‘rate’ and ‘delay’ to be of class Float
and nothing else. There are so many input parameters,
because to me they are all essential in creating a link. So
when a researcher uses my code and he/she just mistakenly
skips one parameter, if the code omits some confusing syntax
error, the researcher may immediately think, “Oh, what a
buggy code”. But if the error message is something like
“input error in method ‘link’: ‘rate’ should be of type
Float, method called from line…”, I think he/she will
simply just immediately correct his/her input. (I know this
does not handle all possible kinds of input errors, such as
negative number, but for now probably some checking is better
than no checking at all, because it at least helps me better.
When (and
if) the GUI is developed in the future, then it will be
full-blown error
checking.)

Can you provide some idea on how to better deal with user
input error using probably some Ruby paradigm?

Regards,

Bill

==============
Dave Thomas Dave@pragmaticprogrammer.com wrote:

Ruby types are not releated to classes. They’re related to object
protocols (the infamous Duck Typing). That’s what gives
Ruby much of
its appeal. Testing for classes is really very poor style, and
artificially constrains the users of your code.

Bignum? AFAIK, it works just like Fixnum only with larger numbers

···

On Tue, 1 Oct 2002 23:09:49 +0900 “Bulat Ziganshin” bulatz@integ.ru wrote:

there is tradeoff between flexibility and reliability. especially for
such types as Fixnum :wink: which has never to be emulated by some other
class


Best regards,
Bulat mailto:bulatz@integ.ru


To call me “awesome” is an understatement.

Hi,

···

In message “Re: thoughts on typelessness” on 02/10/02, “Hal E. Fulton” hal9000@hypermetrics.com writes:

How universal is this terminology, especially
in Rubyland? After all, isn’t #class basically
a synonym for #type?

Forget about #type. It was there because we couldn’t use “class” for
a method name back then.

						matz.

Hi Alan,

All your idea below seems good, but has anything like that been done
before, in some other languages, perhaps?

In parts I know it’s been done, but I don’t know if its been
implemented all together. C++ does some of it at compile time. And
the Java HotSpot VM does runtime optimization. The only real addition
to what I’m proposing is extra profiling logic to determine the class
of objects passing through functions and methods, and optimizing the
most frequent occurences of class parameter signatures. (for lack of a
better term). Once the profiling logic has determined the “internal”
calling signatures, it could proceed like typical compiler in a more
statically typed language.

Let me also try to understand further your idea. Basically, are you
saying that the type of the object referred to by a variable seldom
changes? In this case I agree. So instead of using explicit typing on
the variable itself, let the computer assigns the type to the variable
based on the runtime type of the object referred to by the variable. Am I
correct?

Yes, I think we’re on the same page here. And in the case of multiple
parameters, you would end up with function signatures much like any
language with overloading. Only these signatures are internal to the
compiler. This entire process could be automated like Java, but I
would almose prefer a two stage process - profiling to identify
frequently used signatures then compiling. There could be many
variants to this too, maybe the programmer would like to provide
certain hand-written C-code with signatures accessible to the engine.
In that case, the programmer provided code would be used by the engine
if there was a match.

···

On Wed, Oct 02, 2002 at 12:01:29PM +0900, William Djaja Tjokroaminata wrote:

As I got the impression that Dylan has both static and dynamic typing, I
will also scan the language.

Regards,

Bill

Alan Chen alan@digikata.com wrote:

My whole point was that you might want to consider exploring
optimizations with ruby as is. Optimizations may be more difficult,
but they are certainly possible. When you have application running a
ruby codebase, an optimizing ruby engine (ORE?). In many cases,
parameters passed to function and method calls will be primarily of
the same type. Say function foo(x). In the codebase, maybe x is never
anything but an Array. ORE then creates a block of optimized machine
code assuming x is an array with some detection logic to fallback to
the regular code if x is not an array. Maybe ORE has a “profile” mode,
builds up some run profiling data and them builds the optimized machine
code based on the profile. Or the programmer looks over the profile data
and picks which functions with what type signature to build optimized
code for – all while keeping the Ruby language largely intact, and not
intruducing static typing to function prototypes.


Alan Chen
Digikata LLC
http://digikata.com

Hello William,

Tuesday, October 01, 2002, 7:00:19 PM, you wrote:

  1. i think that

class PositiveFloat < Float
def init
super
raise “…” unless self>0
end
end

will be better

  1. how about ``keyword arguments’'? from “programming ruby” book:

Collecting Hash Arguments

Some languages feature ``keyword arguments’'—that is, instead of passing arguments in a given order and quantity, you pass the name of the argument with its value, in any order. Ruby 1.6 does not have keyword arguments (although they are scheduled to be implemented in Ruby 1.8).

In the meantime, people are using hashes as a way of achieving the same effect. For example, we might consider adding a more powerful named-search facility to our SongList.

class SongList
def createSearch(name, params)
# …
end
end
aList.createSearch(“short jazz songs”, {
‘genre’ => “jazz”,
‘durationLessThan’ => 270
} )

The first parameter is the search name, and the second is a hash literal containing search parameters. The use of a hash means that we can simulate keywords: look for songs with a genre of ``jazz’’ and a duration less than 4 1/2 minutes. However, this approach is slightly clunky, and that set of braces could easily be mistaken for a block associated with the method. So, Ruby has a short cut. You can place key => value pairs in an argument list, as long as they follow any normal arguments and precede any array and block arguments. All these pairs will be collected into a single hash and passed as one argument to the method. No braces are needed.

aList.createSearch(“short jazz songs”,
‘genre’ => “jazz”,
‘durationLessThan’ => 270
)

···

def link (node0, node1, rate = 1e6, delay = 0.0, model = nil, attrs = nil,
type = Link::TYPE_FULL_DUPLEX, label = ‘’, name = ‘’, simStart = false,
simEnd = false, sim = nil)
raise “…” unless rate.kind_of? Float
raise “…” unless delay.kind_of? Float

end

Really, I want the ‘rate’ and ‘delay’ to be of class Float and nothing
else. There are so many input parameters, because to me they are all
essential in creating a link. So when a researcher uses my code and
he/she just mistakenly skips one parameter, if the code omits some
confusing syntax error, the researcher may immediately think, “Oh,
what a buggy code”. But if the error message is something like “input
error in method ‘link’: ‘rate’ should be of type Float, method called
from line…”, I think he/she will simply just immediately correct his/her
input. (I know this does not handle all possible kinds of input errors,
such as negative number, but for now probably some checking is better than
no checking at all, because it at least helps me better. When (and
if) the GUI is developed in the future, then it will be full-blown error
checking.)

Can you provide some idea on how to better deal with user input error
using probably some Ruby paradigm?


Best regards,
Bulat mailto:bulatz@integ.ru

In article ancc8i$ud$1@grapevine.wam.umd.edu,

Hi Dave,

I think in my application it is probably enough to check for classes. For
example, my abstract factory pattern function to create a communications
network link is:

def link (node0, node1, rate = 1e6, delay = 0.0, model = nil, attrs = nil,
type = Link::TYPE_FULL_DUPLEX, label = ‘’, name = ‘’, simStart = false,
simEnd = false, sim = nil)
raise “…” unless rate.kind_of? Float
raise “…” unless delay.kind_of? Float

end

    • Ah ha, at last some code. First of all there is a huge code
      smell here. You are writing Fortran in Ruby. NO method/function
      in any language that supports data structures should have more
      than 3 parameters. ( well maybe 4 in extreme cases.) Certainly,
      in a Ruby method, more than 3 args is suspcicious.
    • Maybe you’d get a lot more out of Ruby if you spent some time
      refactoring your code. I’d start out by making link an object
      rather than a method. It’s no wonder you want types in Ruby,
      types would be a great addition to Fortran.
    • Booker C. Bense
···

William Djaja Tjokroaminata billtj@y.glue.umd.edu wrote:

Hi Alan,

All your idea below seems good, but has anything like that been done
before, in some other languages, perhaps?

There’s a very interesting working example for a language closely related to
Ruby: Psyco, the Python Specializing Compiler. Only on x86, but AFAIK
fully operational and fast.

But it’d probably make more sense to wait for Rite before attempting
anything like that.

···

On Wed, Oct 02, 2002 at 12:01:29PM +0900, William Djaja Tjokroaminata wrote:

Let me also try to understand further your idea. Basically, are you
saying that the type of the object referred to by a variable seldom
changes? In this case I agree. So instead of using explicit typing on
the variable itself, let the computer assigns the type to the variable
based on the runtime type of the object referred to by the variable. Am I
correct?

As I got the impression that Dylan has both static and dynamic typing, I
will also scan the language.

Regards,

Bill


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

Turn right here. No! NO! The OTHER right!

“Duck Typing”, AFAIK, is the idea that if it looks like a duck, if it
quacks like a duck, if it walks like a duck … then, it’s probably a
duck.

If the object looks like a string, acts like a string, responds to the
same methods that an object of type String responds to … then, its
type is that of a String or one that appears like a String.

Read [ruby-talk:26803] and [ruby-talk:26814] …

– Dossy

···

On 2002.10.06, Ryan King rking@panoptic.com wrote:

On 2002.10.01, Dave Thomas Dave@PragmaticProgrammer.com wrote:

def func (a)
    raise "type error" unless a.kind_of? Fixnum
    ....

Ruby types are not releated to classes. They’re related to object
protocols (the infamous Duck Typing). That’s what gives Ruby much of
its appeal. Testing for classes is really very poor style, and
artificially constrains the users of your code.

I can see how type checks like the above would be restrictive,
but I can’t find anything about “Duck Typing” on Google.


Dossy Shiobara mail: dossy@panoptic.com
Panoptic Computer Network web: http://www.panoptic.com/
“He realized the fastest way to change is to laugh at your own
folly – then you can let go and quickly move on.” (p. 70)

Ryan King wrote:

Ruby types are not releated to classes. They’re related to object
protocols (the infamous Duck Typing). That’s what gives Ruby much of
its appeal. Testing for classes is really very poor style, and
artificially constrains the users of your code.

I can see how type checks like the above would be restrictive,
but I can’t find anything about “Duck Typing” on Google.

I take it they mean the old saying “If it walks like a duck, talks like
a duck…”, but I cannot be totally sure.

Look at [ruby-talk:8926] and similar postings.

···

On 2002.10.01, Dave Thomas Dave@PragmaticProgrammer.com wrote:


([ Kent Dahl ]/)_ ~ [ http://www.stud.ntnu.no/~kentda/ ]/~
))_student
/(( _d L b_/ NTNU - graduate engineering - 5. year )
( __õ|õ// ) )Industrial economics and technological management(
_
/ö____/ (_engineering.discipline=Computer::Technology)

Hi Dave,

It seems like a good idea and I think I learn some new Ruby paradigm. :slight_smile:

When I tred it, my only concern is that

"a string".to_f    # >> 0.0, and no runtime error

Is “wibble” supposed to do more on value checking (such as zero and
negative numbers)? The remaining concern then is although it does not
make sense to have a link ‘rate’ of zero, it is perfectly acceptable to
have a link ‘delay’ of zero. So if the user enters

my_method (1e6, '100 msec')

then probably my code cannot help the user much in pinpointing the
source of error, if he/she then is puzzled by the resulting network
simulation result (which is better than what it should be in this case).

Thanks for your suggestion.

Regards,

Bill

···

============================================================================
Dave Thomas Dave@pragmaticprogrammer.com wrote:

Perhaps:

def my_method(rate, delay, ...)
  wibble(rate.to_f, delay.to_f, ....)

Here you’re not insisting that ‘rate’ and ‘delay’ are floats, but
instead that they can yield float values: that they can behave as
floats.