The Artima Developer Community
Sponsored Link

Weblogs Forum
Postfix Typecast Operations

22 replies on 2 pages. Most recent reply: Sep 30, 2005 2:10 PM by Terje Slettebø

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 22 replies on 2 pages [ 1 2 | » ]
Christopher Diggins

Posts: 1215
Nickname: cdiggins
Registered: Feb, 2004

Postfix Typecast Operations (View in Weblogs)
Posted: Sep 27, 2005 10:34 AM
Reply to this message Reply
Summary
The latest HeronScript does type-casting backwards.
Advertisement
I just made a new HeronScript release which supports postfix type-casting. This means the following statements are equivalent:
my_window.line_rel(cm(5), inch(5))
my_window.line_rel(5 cm, 5 inch)
It seems like such an obvious and natural feature for a wide range of domains from physics to engineering to graphics, I wonder why it is so rare? Does any other language actually implement this syntax as a postfix type-cast?


Tanton Gibbs

Posts: 20
Nickname: tanton
Registered: Aug, 2005

Re: Postfix Typecast Operations Posted: Sep 27, 2005 3:07 PM
Reply to this message Reply
Seems to work well for constant integer measurements. However, I'm unsure of how it will look with other constructs. For instance,

do_it( (fun() - that()) cm / (something() * the_other()) sec )

This doesn't have nearly as nice a feel, thus I can imagine the construct has limited usefulness. Considering type casts are usually considered evil, making their use more readable can be a double edged sword. However, in the case of simple metric expressions, I can see an interesting readability advantage. I'm just not sure it scales.

Christopher Diggins

Posts: 1215
Nickname: cdiggins
Registered: Feb, 2004

Re: Postfix Typecast Operations Posted: Sep 27, 2005 4:05 PM
Reply to this message Reply
> Seems to work well for constant integer measurements.
> However, I'm unsure of how it will look with other
> r constructs. For instance,
>
> do_it( (fun() - that()) cm / (something() * the_other())
> sec )
>
> This doesn't have nearly as nice a feel,

Just to be fair the comparison would be to:

do_it( cm(fun() - that()) / sec(something() * the_other())

which doesn't feel very nice neither.

> thus I can
> imagine the construct has limited usefulness.

> Considering
> type casts are usually considered evil,

Type casts are indispensable. How would you convert from an integer to a floating point without a type cast? Or vice versa?

Tanton Gibbs

Posts: 20
Nickname: tanton
Registered: Aug, 2005

Re: Postfix Typecast Operations Posted: Sep 27, 2005 6:27 PM
Reply to this message Reply
> Just to be fair the comparison would be to:
>
> do_it( cm(fun() - that()) / sec(something() *
> the_other())
>
> which doesn't feel very nice neither.

No, I agree. I guess my point was that they don't beautify everything.

> Type casts are indispensable. How would you convert from
> an integer to a floating point without a type cast? Or
> vice versa?

Yes, type casts are indispensable, but that doesn't make them wonderful. Like a sledgehammer, you should avoid them unless you need them. Besides, does 7 float really add readability over float(7). I agree that postfix typecasts are a nice novelty for metrics, but are questionable elsewhere.

Todd Blanchard

Posts: 316
Nickname: tblanchard
Registered: May, 2003

Re: Postfix Typecast Operations Posted: Sep 27, 2005 9:52 PM
Reply to this message Reply
That's how its done in Smalltalk, but the numbers are objects and the 'casts' are messages you send to them to construct new objects from them.

For instance:

1/5 asFloat
3.5 asInteger
'3.14' asNumber

and so forth.

Michael Feathers

Posts: 448
Nickname: mfeathers
Registered: Jul, 2003

Re: Postfix Typecast Operations Posted: Sep 28, 2005 4:49 AM
Reply to this message Reply
You can do something similar with Ruby Rails:

45.minutes + 2.hours + 4.years

Morel Xavier

Posts: 73
Nickname: masklinn
Registered: Sep, 2005

Re: Postfix Typecast Operations Posted: Sep 28, 2005 5:27 AM
Reply to this message Reply
That looks the same, but the meaning is completely different. In what you wrote, there is no typecast, you're calling the "minutes", "hours" and "years" accessors of Fixnum objects.

The only required things were to add these methods to the native Fixnum class (which is equivalent to Java's integers) and create 1+ class to hold them, and overload the addition operator for time arithmetics of course

Christopher Diggins

Posts: 1215
Nickname: cdiggins
Registered: Feb, 2004

Re: Postfix Typecast Operations Posted: Sep 28, 2005 6:09 AM
Reply to this message Reply
In Both the Smalltalk and Ruby example, the notation is simply calling methods of the integer class, isn't it? You can do that in Heron:

5._plus_eq(12)

The real question is can you write code like:

my_window.line_to(25 percent,12 pixels)

in any language, where percent and pixels are user defined types?

Michael Feathers

Posts: 448
Nickname: mfeathers
Registered: Jul, 2003

Re: Postfix Typecast Operations Posted: Sep 28, 2005 6:24 AM
Reply to this message Reply
> In Both the Smalltalk and Ruby example, the notation is
> simply calling methods of the integer class, isn't it? You
> can do that in Heron:
>
> 5._plus_eq(12)
>
> The real question is can you write code like:
>
> my_window.line_to(25 percent,12 pixels)
>
> in any language, where percent and pixels are user defined
> types?


I can't think of any reason why you couldn't do it in any OO language with an open class for the numerics. It would just be a method on that class which constructs and returns another object from self.

Michael Feathers

Posts: 448
Nickname: mfeathers
Registered: Jul, 2003

Re: Postfix Typecast Operations Posted: Sep 28, 2005 6:27 AM
Reply to this message Reply
> That looks the same, but the meaning is completely
> different. In what you wrote, there is no typecast, you're
> calling the "minutes", "hours" and "years" accessors of
> Fixnum objects.

I hear you, but I think that it looks the same and the meaning is the same, it's just that the implementation is different.

Christopher Diggins

Posts: 1215
Nickname: cdiggins
Registered: Feb, 2004

Re: Postfix Typecast Operations Posted: Sep 28, 2005 6:33 AM
Reply to this message Reply
> I can't think of any reason why you couldn't do it in any
> OO language with an open class for the numerics. It would
> just be a method on that class which constructs and
> returns another object from self.

*Christopher humbly admits ignorance*

Open class, what's that? Is it a class which you can add methods to after it is defined? I have heard of such things, but I never got close to one. Which languages support this? Is there other names for this functionality?

Previously, I always automatically dismissed the idea of extending classes post-definition as being something unclean, and which would lead down the road to spaghetti code. Should I rethink this prejudice?

Morel Xavier

Posts: 73
Nickname: masklinn
Registered: Sep, 2005

Re: Postfix Typecast Operations Posted: Sep 28, 2005 7:24 AM
Reply to this message Reply
> > That looks the same, but the meaning is completely
> > different. In what you wrote, there is no typecast,
> you're
> > calling the "minutes", "hours" and "years" accessors of
> > Fixnum objects.
>
> I hear you, but I think that it looks the same and the
> meaning is the same, it's just that the implementation is
> different.

It does look the same indeed, but the meaning is very different, what is done in Ruby is not a cast, or a type declaration, it's the access to a reading property. Said property (2.hours) may return an "Hour" object, but it may as well return another Fixnum, or a string, or whatever the author wanted it to return.

What Christopher wants to create here is not a property of an object, but a type declaration / typecast.
> > I can't think of any reason why you couldn't do it in
> any
> > OO language with an open class for the numerics. It
> would
> > just be a method on that class which constructs and
> > returns another object from self.
>
> *Christopher humbly admits ignorance*
>
> Open class, what's that? Is it a class which you can add
> methods to after it is defined?
I guess it is

> I have heard of such
> things, but I never got close to one. Which languages
> support this? Is there other names for this functionality?
>
Well, prototyping languages probably would, Javascript does allow you to extend base types (Array.prototype.whatever = function () {} will create a new method of every Array object)

Ruby allows you to "reopen" a class whenever you want, example one would be
[fixed]class MyClass
attr_accessor :data
def initialize
@data = 5
end
end

o = MyClass.new
o.data
> 5

class MyClass
def data
@data*5
end
def data=(value)
@data = value/5
end
end

o.data
> 25
o.data = 4 # o.data is an integer, 4 is too, should yield 0
o.data
> 0[/fixed]

And this ability is available in Python too, though a bit more difficult to use: your class is an objet, you add a new member (method) to your class.
[fixed]>>> class MyObject(object):
... def __init__(self):
... self.foo = "bar"
...
>>> a = MyObject()
>>> a.foo
'bar'
>>> a.setFoo('b')
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: 'MyObject' object has no attribute 'setFoo'
>>> def f(self,val): # here I create my new method as a
... self.foo = val # standalone object
...
>>> MyObject.setFoo = f # and I bind it to my class
>>> a.setFoo('b')
>>> a.foo
'b'[/fixed]

Python doesn't allow you to extend builtin types that way though, while ruby does:
[fixed]irb(main):001:0> 2.test
NoMethodError: private method `test' called for 2:Fixnum
from (irb):1
from :0
irb(main):002:0> class Fixnum
irb(main):003:1> def test
irb(main):004:2> "ok"
irb(main):005:2> end
irb(main):006:1> end
=> nil
irb(main):007:0> 2.test
=> "ok"
irb(main):008:0> [/fixed]
This is very powerful as it allows for easy extension of base types, but extremely dangerous since you may get collision between modules modifying base types. Handle with care

> Previously, I always automatically dismissed the idea of
> extending classes post-definition as being something
> unclean, and which would lead down the road to spaghetti
> code. Should I rethink this prejudice?
I'm not sure it could lead to spaggethi code, in Javascript, which has quite useless base types, it's a very handy way to extend these types and have them actually do useful things (you can add slices, iterators, ... to JS' arrays that way).

The issue is when just about everyone starts doing it, you don't end with spaggethi code but you end with unreliable standard types, which is why I think that kind of extensions should be done only when necessary and should be explicitely and extensively documented.

Keith Ray

Posts: 658
Nickname: keithray
Registered: May, 2003

Re: Postfix Typecast Operations Posted: Sep 28, 2005 7:31 AM
Reply to this message Reply
Objective-C, Smalltalk and Ruby (and Python?) allow methods to be added to pre-existing classes.

If you want a large-scale, commercial-quality example where someone has added methods to pre-existing classes, look at the Omni frameworks, http://www.omnigroup.com/developer/sourcecode/

I believe elsewhere in this blog you conflated type-casting with type-conversion. They are NOT the same thing. The language "C" (and by derivation, C++) unfortunately used the same syntax for type-casting and type-conversion.

Type-casting is for you to the tell the compiler that the type "really" is -- in other words, you know more than the compiler does at the point in the source code. In C,

float aFloat = 12.13;
long aLong = *(long*)&aFloat;

does a type-cast so you can use a long to look at the unchanged bits of a float. (assumes both are 32-bits wide).

Also in C,

float aFloat = 12.13;
long aLong = (long) aFloat;

does a type-conversion so the long variable contains 12 -- a different pattern of bits than the float value of 12.13.

In languages in which variables do not have declared types (note that while the variables are 'typeless', the objects do have types!) there is no need for type-casting. Type-conversion is performed by methods. So the Float class and Integer classes in Smalltalk have methods to convert from one to the other. "12 asFloat" would be calling such a method on the Integer object 12.

Michel Parisien

Posts: 25
Nickname: kriggs
Registered: Jul, 2005

Re: Postfix Typecast Operations Posted: Sep 28, 2005 7:43 AM
Reply to this message Reply
> > Seems to work well for constant integer measurements.
> > However, I'm unsure of how it will look with other
> > r constructs. For instance,
> >
> > do_it( (fun() - that()) cm / (something() *
> the_other())
> > sec )
> >
> > This doesn't have nearly as nice a feel,
>
> Just to be fair the comparison would be to:
>
> do_it( cm(fun() - that()) / sec(something() *
> the_other())
>
> which doesn't feel very nice neither.

First off, I will start by saying that, in my opinion, the reason why your example does not feel right is that your casting is done the same way you would use a function. Functions use verbs, so our brains make verbs out of them: "centimeter the fun minus that", as opposed to your prefered "the fun minus that centimeters". Which I'll admit does sound nicer, but is it warrented?

Whenever I see anyone play with the ordering of the syntax, it always raises an internal flag... First of all, let's go with a more traditional, less ambiguous way of prefixing a cast:

do_it((cm)(fun() - that()) / (sec)(something() * the_other())

This personally feels just as good as with using a suffix (of course, this line of code itself in real code should maybe be broken up into parts). But if trying to map your language to English is your concern, tell me how you would, for example, make a function that checks if a number divides another? divides(a, b)? In a stream of code, this looks weird, because the verb tense is different than all the other function verbs. Of course, in normal math, you would do "a divides b", but again that is playing with the ordering of your language. Would it be worth it in this case too?

I just think that using suffixes can probably be used for something better in the future than just another way of doing casting. We already have one of those.

As a side question, will you have a different type for every combination, such as having a type that is cm^4/sec^2*kg^3? I guess when there is a type that isn't used much in the real world, you could have a catch-all type that just keeps track of how many of each unittype there is.

> > thus I can
> > imagine the construct has limited usefulness.
>
> > Considering
> > type casts are usually considered evil,
>
> Type casts are indispensable. How would you convert from
> an integer to a floating point without a type cast? Or
> vice versa?

Well I agree with them being evil, but not in the sense of "don't use them", but in the sense of "use them cautiously". All casts lose or transform some information of an object, making them dangerous to use if you're not being careful (by dangerous, I mean compile time or run time error). In your case, going from float to int definately loses some information, and going from int to float loses the integer part precision of the number. Of course you need casts, but I have seen code where it was obvious those developing it didn't know what type they were using, and it ended up going through two float casts and two int casts, and that is why the resulting number was so out of whack. Still, I cannot imagine how one could use a language without casts (unless it is a single type language), and even a language without some implicit casting would look ugly at times.

Christopher Diggins

Posts: 1215
Nickname: cdiggins
Registered: Feb, 2004

Re: Postfix Typecast Operations Posted: Sep 28, 2005 7:54 AM
Reply to this message Reply
> Objective-C, Smalltalk and Ruby (and Python?) allow
> methods to be added to pre-existing classes.
>
> If you want a large-scale, commercial-quality example
> where someone has added methods to pre-existing classes,
> look at the Omni frameworks,
> http://www.omnigroup.com/developer/sourcecode/

Thanks for this information and the link.

> I believe elsewhere in this blog you conflated
> type-casting with type-conversion. They are NOT the same
> thing. The language "C" (and by derivation, C++)
> unfortunately used the same syntax for type-casting and
> type-conversion.

Common usage disagrees with your definition of typecasting. The action of converting a value of type float to type int, is very widely referred to as a "typecast", and has been for quite some time even outside of the C/C++ community.

Flat View: This topic has 22 replies on 2 pages [ 1  2 | » ]
Topic: The Temporary Assignment Problem and Transfer Semantics Previous Topic   Next Topic Topic: Metaprogramming on Steroids: Overloaded Type Operators

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use