The Artima Developer Community
Sponsored Link

Weblogs Forum
Embedded DSLs and Productivity

43 replies on 3 pages. Most recent reply: Apr 22, 2006 7:13 AM by Andy Dent

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 43 replies on 3 pages [ « | 1 2 3 ]
Isaac Gouy

Posts: 527
Nickname: igouy
Registered: Jul, 2003

Re: Embedded DSLs and Productivity Posted: Apr 12, 2006 5:49 PM
Reply to this message Reply
Advertisement
take a look at functional languages and combinator libraries (try googling for "combinator library")
Or perhaps an old paper like "Domain Specific Embedded Compilers"
http://citeseer.ist.psu.edu/leijen99domain.html

Isaac Gouy

Posts: 527
Nickname: igouy
Registered: Jul, 2003

Re: Embedded DSLs and Productivity Posted: Apr 12, 2006 6:47 PM
Reply to this message Reply
what I mean by static typing is that every variable and expression in a program has a type that is known at compile time. It is "static" to me because those things can't change at runtime.
In languages with subtypes and interfaces those things can't change at runtime isn't as restrictive.

invoke methods by looking for a signature that matches (since your variable holding the reference to the object on which you're invoking the method doesn't itself have a type)
Looking for a signature that matches what? :-)
iirc Java static methods early bind on the static type, Java instance methods may late bind using runtime method dispatch.

> To me the most fundamental tradeoff between these two
> approaches is that the static approach allows you to do
> all kinds of analysis, including but not limited to type
> checking at compile time, better IDE refactoring, better
> optimization at runtime. The dynamic approach gives you a
> lot of flexibility to do slippery things like dynamic
> meta-programming, which helps programmer productivity. You
> can't do that slippery stuff as much in a static language,
> because once the types have passed the compiler, you can't
> change them anymore. You can change them in source as much
> as you want, but after that, they are static--they stay
> the same.

imo it's really difficult to avoid conflating things when we use the shorthand slogans static/dynamic.

afaict the Java metaprogramming problem has a lot to do with the limited implementation of reflection, and not much to do with whether variables are constrained by type. (My impression is that .Net System.Reflection.Emit does things better.)

afaict not constraining variables by type doesn't prevent static type analysis - the best example I know is the Erlang Dialyzer
http://www.it.uu.se/research/group/hipe/dialyzer/

Bill Venners

Posts: 2250
Nickname: bv
Registered: Jan, 2002

Re: Embedded DSLs and Productivity Posted: Apr 12, 2006 8:13 PM
Reply to this message Reply
> what I mean by static typing is that every variable and
> expression in a program has a type that is known at
> compile time. It is "static" to me because those things
> can't change at runtime.

> In languages with subtypes and interfaces those things
> can't change at runtime
isn't as restrictive.
>
That's true. In Java I can quite easily load a class dynamically that wasn't known about at compile time and use it from a variable typed as one of the class's supertypes. But at runtime, those supertypes don't change. In a dynamic language such as Ruby, they can.

> invoke methods by looking for a signature that matches
> (since your variable holding the reference to the object
> on which you're invoking the method doesn't itself have a
> type)

> Looking for a signature that matches what? :-)
> iirc Java static methods early bind on the static type,
> Java instance methods may late bind using runtime
> method dispatch.
>
True, but in both cases in Java, you bind not just on the signature, but also on the type. In a dynamic language you just bind on the signature.

Isaac Gouy

Posts: 527
Nickname: igouy
Registered: Jul, 2003

Re: Embedded DSLs and Productivity Posted: Apr 12, 2006 9:57 PM
Reply to this message Reply
-snip-
Bill Venners wrote
> That's true. In Java I can quite easily load a class
> dynamically that wasn't known about at compile time and
> use it from a variable typed as one of the class's
> supertypes. But at runtime, those supertypes don't change.
> In a dynamic language such as Ruby, they can.

What if the supertype is a universal type like Object?
We can assign all manner of different types to a variable typed as the universal type - just like Ruby.
Is it easier to think of Ruby variables typed as one thing, and then changing to be typed as another thing, and then another; or is it easier to think of Ruby variables typed as the universal type?

-snip-
Bill Venners wrote
> True, but in both cases in Java, you bind not just on the
> signature, but also on the type. In a dynamic language you
> just bind on the signature.

iirc a Java method signature includes the parameter types and return type.

In Smalltalk method lookup starts in the class of the object to which the message was sent, and climbs up through the inheritance hierarchy, trying to match the method selector - so binding is based on the receiver object class and the method selector.

Of course, we should expect that these implementation details will be different in different "dynamic" languages.

Isaac Gouy

Posts: 527
Nickname: igouy
Registered: Jul, 2003

Re: Embedded DSLs and Productivity Posted: Apr 12, 2006 10:43 PM
Reply to this message Reply
> That may capture much of what Keith Braithwaite is trying
> to say about productivity with Smalltalk.

"When you make an object that has a protocol that's a mini-language in it's own right..."

Ward Cunningham, mp3 podcast interview
http://www.gridsummit.com/Multimedia/WardC_24K.mp3

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: Embedded DSLs and Productivity Posted: Apr 13, 2006 10:12 AM
Reply to this message Reply
> With generic collections there's no need for (String) so
> why do you want implied casts?

Generics doesn't elminate the need for explicit casts. For example, if you are deserializing Objects and adding them to a List<String>, you need to cast the Objects to Strings before adding them.

Bill Venners

Posts: 2250
Nickname: bv
Registered: Jan, 2002

Re: Embedded DSLs and Productivity Posted: Apr 13, 2006 11:18 AM
Reply to this message Reply
> What if the supertype is a universal type like
> Object?
> We can assign all manner of different types to a variable
> typed as the universal type - just like Ruby.
> Is it easier to think of Ruby variables typed as one
> thing, and then changing to be typed as another thing, and
> then another; or is it easier to think of Ruby variables
> typed as the universal type?
>
Well, my point is that if the type of the variable is Object, you can only call the methods on the object it references that are defined in class Object. Even if the actual object is String, you can only call the Object methods from a variable of type Object. To call charAt(), you have to explicitly downcast the variable type to String, at which point you can call the String methods.

In Ruby's case, you can call whatever method you want, and if the receiving object has a signature that matches, it will be executed.

> -snip-
> Bill Venners wrote
> > True, but in both cases in Java, you bind not just on
> the
> > signature, but also on the type. In a dynamic language
> you
> > just bind on the signature.
>
> iirc a Java method signature includes the parameter types
> and return type.
>
> In Smalltalk method lookup starts in the class of the
> object to which the message was sent, and climbs up
> through the inheritance hierarchy, trying to match the
> method selector - so binding is based on the receiver
> object class and the method selector.
>
Oops, good point. I need to be more precise. In fact, the JVM does a similar kind of searching up the inheritance hierarchy when it performs dynamic linking of instance methods. The difference is that in the Smalltalk case, the class of object can be anything so long as it sports a matching method signature. In the Java case, the class of the object is restricted to the type of the variable or a subtype of that variable type. Moreover, that type restriction is defined at the source code level, so you don't have to run the program to find out what that restriction is, even though you have to run the program to find out what the actual class is in each case. Because the type restriction is defined at the source code level, that information is available to static analysers.

Isaac Gouy

Posts: 527
Nickname: igouy
Registered: Jul, 2003

Re: Embedded DSLs and Productivity Posted: Apr 13, 2006 2:12 PM
Reply to this message Reply
Bill Venners Well, my point is that...
class MyObj {
   public void dostuff(){}
   public static void main(String[] args) {
      Object o;
      o = "2452";
      o = 23.1;
      o = new MyObj();
      o.dostuff();
    }
}
The big practical difference between this and say Ruby isn't that variables are typed - it's that we type-check using those variable types.
>javac MyObj.java
MyObj.java:9: cannot find symbol
symbol : method dostuff()
location: class java.lang.Object
o.dostuff();
^
1 error
In Ruby's case, you can call whatever method you want, and if the receiving object has a signature that matches, it will be executed.
In Ruby's case we don't type-check at compile-time, so we proceed without error to run-time.

(It's generally true that in statically type checked languages variables are typed, and in dynamically type checked languages variables are not typed, but afaict that's little-stuff until we use those variable types in static type-checking.)


Bill Venners I need to be more precise.
We all need to be more precise :-)

the JVM does a similar kind of searching up the inheritance hierarchy when it performs dynamic linking of instance methods. The difference is that in the Smalltalk case, the class of object can be anything so long as it sports a matching method signature.
The first difference is that javac static type checking will prevent o.dostuff();

And let's be clear, there is no "so long as it sports a matching method signature".

In Smalltalk we send any message selector to an object, and the object will do something - but that something might be to say that the object doesn't understand the message selector.

(Bad analogy: we can request both http://www.ttttttttttttttttttttttttt.com/ and http://www.ttttt.com/ but we have to wait until we receive the reply to know which will be "Server not found")

Bill Venners

Posts: 2250
Nickname: bv
Registered: Jan, 2002

Re: Embedded DSLs and Productivity Posted: Apr 13, 2006 4:03 PM
Reply to this message Reply
> The big practical difference between this and say
> Ruby isn't that variables are typed - it's that we
> type-check using those variable types
.

> (It's generally true that in statically type checked
> languages variables are typed, and in dynamically type
> checked languages variables are not typed, but afaict
> that's little-stuff until we use those variable types in
> static type-checking.)
>
Well here I'd say that more generally. The practical difference is that the greater amount of type information, the types of those variables in a statically typed language, gives more information for static analysis. Type checking done by a compiler is one kind of static analysis, but not the only kind that useful to us. My Java IDE uses static analysis to help me perform refactors, for example. Enabling that refactoring is a very practical difference between a statically and dynamically typed language. What makes that kind of static analysis possible is that all variables and expressions have types, which is why I put the emphasis there.

> And let's be clear, there is no "so long as it
> sports a matching method signature"
.
>
> In Smalltalk we send any message selector to an object,
> and the object will do something - but that something
> might be to say that the object doesn't understand the
> message selector.
>
Yes, that's another good point. Also in Ruby you can define a method that wil be invoked if a missing method is invoked, the default of which is to throw an exception. In Java you just get an exception, that is, if the problem wasn't caught at compile time.

Vesa Karvonen

Posts: 116
Nickname: vkarvone
Registered: Jun, 2004

Casts not needed Posted: Apr 13, 2006 5:15 PM
Reply to this message Reply
Generics doesn't elminate the need for explicit casts. For example, if you are deserializing Objects and adding them to a List<String>, you need to cast the Objects to Strings before adding them.

This probably isn't what you mean, but it is a myth that the only way to do serialization is through a language feature known as "casts". Yes, even despite the fact that libraries in many languages do it that way. For evidence, see, for example, the papers referred to on the following page http://mlton.org/Serialization.

More generally, I believe that many people coming from a C/C++ background (not referring to any particular person here) think that unsafe casts and other unsafe language features are a necessary feature of programming languages.

Thinking about this recently, I came to think that the idea of types deeply rooted in languages like C is that you create a type to specify how many bits of memory you want to allocate (just look at union in C and C++). You then use a host unsafe operations to manipulate those bits (like malloc, free, memcmp, memcpy, ...) essentially violating the very type specification you wrote. It is quite standard practise to manipulate raw memory. Fundamentally, the types in C aren't there to enforce abstraction. The types are there for the compiler to choose machine instructions (e.g. whether to perform 8-bit, 16-bit or 32-bit addition).

So, when programmers with a strong C background meet high-level type safe languages, they feel quite uneasy. How on earth can anything non-trivial be done without memcpy and friends? How can one access raw memory and hand-optimize the bit-level layout of data structures?

Isaac Gouy

Posts: 527
Nickname: igouy
Registered: Jul, 2003

Re: Embedded DSLs and Productivity Posted: Apr 13, 2006 5:23 PM
Reply to this message Reply
Bill Venners wrote Well here I'd say that more generally...
I'm moving in smaller steps :-)

Type checking done by a compiler is one kind of static analysis, but not the only kind that useful to us...
Do we agree that it is static type checking that prevents Ruby like dynamic lookup for o.dostuff();?

Bill Venners wrote What makes that kind of static analysis possible is that all variables and expressions have types, which is why I put the emphasis there.
Yes as-long-as we are unable to infer variable types, when the language doesn't require variables (or methods) to be typed.

James Watson

Posts: 2024
Nickname: watson
Registered: Sep, 2005

Re: Casts not needed Posted: Apr 13, 2006 6:04 PM
Reply to this message Reply
> Generics doesn't elminate the need for explicit casts.
> For example, if you are deserializing Objects and adding
> them to a List<String>, you need to cast the Objects to
> Strings before adding them.

>
> This probably isn't what you mean, but it is a myth
> that the only way to do serialization is through a
> language feature known as "casts". Yes, even despite the
> fact that libraries in many languages do it that way. For
> evidence, see, for example, the papers referred to on the
> following page http://mlton.org/Serialization.

I followed that path a little ways but I wasn't sure I was reading what meant to point me to. Could you give a more direct link? I ended up reading what appeared to be about Python which doesn't support static typing.

> More generally, I believe that many people coming from a
> C/C++ background (not referring to any particular person
> here) think that unsafe casts and other unsafe language
> features are a necessary feature of programming
> languages.

You've got my attention. I was really referring to Java only, but how can you create a data structure (safely) from a raw stream without checking at some point that it's valid?

> So, when programmers with a strong C background meet
> high-level type safe languages, they feel quite uneasy.
> How on earth can anything non-trivial be done without
> memcpy and friends? How can one access raw memory and
> hand-optimize the bit-level layout of data structures?

I guess that's kind of the 'Mel' syndrome, isn't it?

Isaac Gouy

Posts: 527
Nickname: igouy
Registered: Jul, 2003

Re: Casts not needed Posted: Apr 14, 2006 12:06 PM
Reply to this message Reply
James Watson wrote
-snip-
> You've got my attention. I was really referring to Java
> only, but how can you create a data structure (safely)
> from a raw stream without checking at some point that it's
> valid?

Maybe there's just some slippage in what we mean by "checking"?

"Clean expressions can be written to disk as a dynamic, which contains a representation of their (polymorphic) static type, while preserving sharing. Clean programs can load dynamics from disk and use run-time type pattern matching to reintegrate it into the statically typed program. In this way, new functionality (e.g. plug-ins) can be added to a running program in a type safe way."
ftp://ftp.cs.kun.nl/pub/Clean/papers/2004/vWeA2004-Esther.pdf

Andy Dent

Posts: 165
Nickname: andydent
Registered: Nov, 2005

Re: Embedded DSLs and Productivity Posted: Apr 22, 2006 7:13 AM
Reply to this message Reply
I think the influence of the environment has been vastly underestimated.

How many people have used a truly Smalltalk-like browser environment to write their Java or C++?

Some of the best coding experienced and certainly most productive times I have had were using the late, lamented ObjectMaster IDE for C++ coding.

It provided the classic Smalltalk three-pane browser for selecting classes, methods and properties, with the editing area underneath being class definition, text of a method etc. depending on your actions above.

You could have multiple browser windows open for methods in the same file, hiding the textual file basis of the core language.

I could rave on and on but have already done so in a review back in 1994
http://www.mactech.com/articles/mactech/Vol.10/10.12/ObjectMaster/

Yep, in 12 years since I have yet to find as productive an environment for c++ coding. I still use it, for code that doesn't have namespaces.

Flat View: This topic has 43 replies on 3 pages [ « | 1  2  3 ]
Topic: Embedded DSLs and Productivity Previous Topic   Next Topic Topic: When Designs Matter


Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2014 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us