Fwd: Re: [scala-user] benefit of dynamic typing?

30 views
Skip to first unread message

HamsterofDeath

unread,
Feb 8, 2011, 4:50:54 PM2/8/11
to scala...@googlegroups.com


-------- Original-Nachricht --------
Betreff: Re: [scala-user] benefit of dynamic typing?
Datum: Tue, 08 Feb 2011 22:50:37 +0100
Von: HamsterofDeath <h-s...@gmx.de>
An: Jim Powers <j...@casapowers.com>



Rails ActiveRecord - Active record creates objects on the fly with attributes (getters and setters) based on "what came back" from a SQL query.

For instance:

If I instantiate an AR object tied to the following SQL:

SELECT bar, baz FROM foo

My resulting AR objects will respond to bar and baz:

row = Foo.find(...)
row.bar # works
row.baz # works

Now, say you use the following SQL

SELECT bar, baz, <computed expression> goo FROM foo

row = Foo.find(...)
row.bar # works
row.baz # works
row.goo # works!


i do not see an advantage. you have to magically know that the row-instance you are working on has bar, baz and goo. you also have to magically know what the types of these attributes are to be able to properly work with them. there is no difference to a construct like this:
val whatever = row.getField("goo").asInstanceOf[MagicallyKnownType] // class dynamically generated at runtime
or this:
row.get("goo").asInstanceOf[MagicallyKnownType] // a simple map
which you could both write as:
row[MagicallyKnownType]("goo") // using apply

now assume you got it wrong and goo is actually an instance of Goo instead of MagicallyKnownType. the statically typed version will fail somewhere in apply, the dynamically typed will fail at a random point when you try to access one of MagicallyKnownTypes methods or fields. it might fail sooner or later.
so even in the example you provided, i'd prefer the statically typed version because its time bomb goes off sooner.

(my real reason for preferring static typing is that i have to think less and can "navigate" more easily - no need for manual data flow analysis to understand what's going on)




Jim Powers

unread,
Feb 8, 2011, 5:18:00 PM2/8/11
to scala...@googlegroups.com
> Rails ActiveRecord - Active record creates objects on the fly with attributes (getters and setters) based on "what came back" from a SQL query.
> For instance:
> If I instantiate an AR object tied to the following SQL:
> SELECT bar, baz FROM foo
> My resulting AR objects will respond to bar and baz:
> row = Foo.find(...)
> row.bar # works
> row.baz # works
> Now, say you use the following SQL
> SELECT bar, baz, <computed expression> goo FROM foo
>
> row = Foo.find(...)
> row.bar # works
> row.baz # works
> row.goo # works!
>
> i do not see an advantage. you have to magically know that the row-instance you are working on has bar, baz and goo. you also have to magically know what the types of these attributes are to be able to properly work with them. there is no difference to a construct like this:
> val whatever = row.getField("goo").asInstanceOf[MagicallyKnownType] // class dynamically generated at runtime
> or this:
> row.get("goo").asInstanceOf[MagicallyKnownType] // a simple map
> which you could both write as:
> row[MagicallyKnownType]("goo") // using apply
>
> now assume you got it wrong and goo is actually an instance of Goo instead of MagicallyKnownType. the statically typed version will fail somewhere in apply, the dynamically typed will fail at a random point when you try to access one of MagicallyKnownTypes methods or fields. it might fail sooner or later.
> so even in the example you provided, i'd prefer the statically typed version because its time bomb goes off sooner.
>
> (my real reason for preferring static typing is that i have to think less and can "navigate" more easily - no need for manual data flow analysis to understand what's going on)

No doubt.

I'm guessing that the mailing list is probably not super-interested in
a protracted "discussion" of this issue ;-), so I'll let this be my
last response on the issue:

RE: "What I thought was a Foo was actually a Goo"
Yup, moving (some) compile time checking to run-time. Although I do
fully understand the trade-offs a considerable amount of this kind of
coding happens all the time. Typically, incorrectly thinking you have
a Foo when you have a Goo, really only matters if a Goo does not
respond to the same messages (protocol) as a Foo. Often beyond that
it doesn't matter. It's called "duck-typing" and is rather common.
In many cases (especially expressing the results of SQL queries in
"another" language) what you call "a thing" (it's type) doesn't really
matter. All that matters is that it responds to the "messages" I send
it (Ruby really is just a MPI kind of language). Whether this is or
is not an advantage I guess depends on your point of view: quite a lot
of code gets written this way, considerably more than the code written
in Scala, Haskell, Clean, SML, OCaml, etc. Popularity is not a
"deciding" metric on it's own, but I would guess that dynamically
typed languages just seem more approachable. On the other hand
statically typed languages help the programmer state up-front all the
entities under consideration.

RE: data-flow analysis
Hrm. I must admit that I still struggle with Scala's type system.
Although I can use a number of features in Scalaz, for instance, I'm
not 100% clear on how all it works. For example, things like this:
https://gist.github.com/66925 are nowhere immediately obvious pieces
of code. I find myself in the REPL trying my darnedest to figure out
what the compiler is doing. I find it frustrating unraveling that
kind of data flow analysis. And as Tony and others on the Scalaz team
have pointed out sometimes, if you're not completely clear, the
compiler will resolve the type constraints with a different type than
you expect. I also do understand that this is due to the limitations
of the Scala language and type system, but ferreting out what's going
on is equally daunting, and typically not straight-forward.


--
Jim Powers

Tomás Lázaro

unread,
Feb 8, 2011, 5:20:53 PM2/8/11
to Jim Powers, scala...@googlegroups.com
I noticed it most comments come down to: "_ person is _ with _ language"... No real arguments...

- The "Old Article I Wrote" mentioned earlier is really constructive (http://cdsmith.wordpress.com/2011/01/09/an-old-article-i-wrote/)
- The mocking/testing discussion is constructive
- ActiveRecord vs Scala way is constructive
- http://rigaux.org/language-study/scripting-language/ is a nice place to have an idea of what people expect from "scripting" languages

As pointed before most people here, myself included, is mostly inclined towards "static typing/strongly typing" watchamacallit, (Scala style at least).

On the other hand I feel like most stuff suggested in favor o "Dynamic Languages" is always doable in Scala with most of the objectives accomplished. In the end it's always a way to enrich my view of Scala and programming in general.

Any more examples of places were dynamic languages show their good qualities?

Ivan Porto Carrero

unread,
Feb 8, 2011, 5:38:38 PM2/8/11
to scala...@googlegroups.com
I've found the ability to rebind methods or closures to a different receiver to be very helpful in creating internal dsl's

In most dyn langs I can do the following

....
a = lambda { |some| #code which calls other instance methods }
C.new.instance_exec(a)
....

var a = function(some){ //code which calls other instance methods }
var c = new C()
a.apply(c)


This means I don't have to pass in an execution context into my closure but can skip that one parameter

ruby:
HttpStream.listen :channel_name do 
  on :received do |message|
    send "echo #{message}"
  end
end

Scala:
HttpStream.listen('channelName) { channel =>
   channel.on('received) { (session, message) => 
     session.send("echo %s" format message)
   } 
}

That's one use case where dynamic typing is useful

I often find myself wishing I could build new combinations of traits at runtime and create an instance from them.  
---
Met vriendelijke groeten - Best regards - Salutations

Ivan Porto Carrero


2011/2/8 Tomás Lázaro <tlaz...@gmail.com>

Vlad Patryshev

unread,
Feb 8, 2011, 6:43:54 PM2/8/11
to HamsterofDeath, scala...@googlegroups.com
What you are describing is a typical practice of those working, say, with Hibernate. You have dates in your table, and they are nullable, and suddenly kaboom, by default each null in the row causes a weird runtime error. You overwrite those null dates with '0000-00-00', and expect it to be a zero date, magically, but kaboom again, it does not work, and it's runtime. Sure it is wrong data, but hmm, how come nobody is able to generate the right type, something like OptionalDate, or just Option[Date]?

What I want to say, this magic is really a bad service... but cheap, yes.

2011/2/8 HamsterofDeath <h-s...@gmx.de>



--
Thanks,
-Vlad

Volodymyr Kyrychenko

unread,
Feb 8, 2011, 6:58:30 PM2/8/11
to scala...@googlegroups.com
HamsterofDeath wrote:
> so even in the example you provided, i'd prefer the statically typed
> version because its time bomb goes off sooner.

When the most of your code works with external systems - for instance
web-services, than the point of runtime failure is an external system,
and compiler checks for the typing correctness of the program checks
actually nothing, because you'll get runtime type error anyway, and
there is nothing you can do with it. So if the static typing can't grant
anything anyway - why bother with asInstanceOf[]?

Another reason that only part (which is not the one you're using) could
be altered - for the dynamic language it's fine. Imaging if
bash-scripting was statically typed. In this case scripts should be
"compiled" against very particular versions of utilities. If something
changes in 'ls' - go 'recompile' your scripts. For the small scripting
purposes or integration purposes dynamic typing is good not because it
has some particular advantages over static typing, but because static
typing has disadvantages in this case - too much checks those grant nothing.

--
Best Regards,
Volodymyr Kyrychenko

signature.asc

Ittay Dror

unread,
Feb 8, 2011, 11:31:49 PM2/8/11
to scala...@googlegroups.com

Web applications. The reason is that they interact with a user over
HTTP, creating HTML, and reading from a database. All these operations
are not type safe. The application then needs to do a lot of conversion
/ reflection. It doesn't matter whether this is done in a static/dynamic
languages. The dynamic languages are more oriented towards dealing with
untyped data.

Ittay

Dennis Haupt

unread,
Feb 9, 2011, 3:25:21 AM2/9/11
to Volodymyr Kyrychenko, scala...@googlegroups.com

-------- Original-Nachricht --------
> Datum: Wed, 09 Feb 2011 01:58:30 +0200
> Von: Volodymyr Kyrychenko <vladimir....@gmail.com>
> An:
> CC: scala...@googlegroups.com
> Betreff: Re: Fwd: Re: [scala-user] benefit of dynamic typing?

> HamsterofDeath wrote:
> > so even in the example you provided, i'd prefer the statically typed
> > version because its time bomb goes off sooner.
>
> When the most of your code works with external systems - for instance
> web-services, than the point of runtime failure is an external system,
> and compiler checks for the typing correctness of the program checks
> actually nothing, because you'll get runtime type error anyway, and
> there is nothing you can do with it. So if the static typing can't grant
> anything anyway - why bother with asInstanceOf[]?

i see similarities to "null vs Option[Type]" here. null is simpler, but can become time bomb and explode at a random time when you actually try to access the object which makes it more difficult to find the source of the problem. explicitly checking as soon as possible acts as a guard against this.

>
> Another reason that only part (which is not the one you're using) could
> be altered - for the dynamic language it's fine. Imaging if
> bash-scripting was statically typed. In this case scripts should be
> "compiled" against very particular versions of utilities. If something
> changes in 'ls' - go 'recompile' your scripts. For the small scripting
> purposes or integration purposes dynamic typing is good not because it
> has some particular advantages over static typing, but because static
> typing has disadvantages in this case - too much checks those grant
> nothing.

i see. so basically, "dynamic typing" means "i know more than the compiler does." i thought about this. imho, a hybrid would be best. for example Finder.find("select a,b,c from x") should return a TupleN with correct generic type parameters. the compiler should be able to understand the given sql statement and construct a class/type from it, so the benefits of static typing (code completion ftw) can be used as well as multiple return types.

Randall R Schulz

unread,
Feb 9, 2011, 9:39:23 AM2/9/11
to scala...@googlegroups.com
On Tuesday February 8 2011, Ittay Dror wrote:
> ... The dynamic languages are more oriented

> towards dealing with untyped data.

There is no such thing as "untyped data."


> Ittay


Randall Schulz

Razvan Cojocaru

unread,
Feb 9, 2011, 11:03:03 AM2/9/11
to Ivan Porto Carrero, scala...@googlegroups.com

>> I often find myself wishing I could build new combinations of traits at runtime and create an instance from them.  

 

What exactly do you mean by that? Something like an anonymous class? Do you imply that you don’t know the traits you want to mixin until you actually run?

 

Razvan

Dennis Haupt

unread,
Feb 9, 2011, 11:14:30 AM2/9/11
to Razvan Cojocaru, scala...@googlegroups.com, iv...@mojolly.com
he probably wants to do something like this:
val p = new Person("harry","potter")
val realMagic = p with UpperCaseNames // right now, you'd have to write "new PersonThatDelegatesAllCallsTo(p) with UpperCaseNames" and provide your own implementation of PersonThatDelegatesAllCallsTo

one step further:
you don't know at compile time if it will be the UpperCase- or ReverseNames-trait.

-------- Original-Nachricht --------
> Datum: Wed, 9 Feb 2011 11:03:03 -0500
> Von: "Razvan Cojocaru" <p...@razie.com>
> An: "\'Ivan Porto Carrero\'" <iv...@mojolly.com>, scala...@googlegroups.com
> Betreff: RE: Re: [scala-user] benefit of dynamic typing?

Jim Powers

unread,
Feb 9, 2011, 11:16:46 AM2/9/11
to scala...@googlegroups.com
On Wed, Feb 9, 2011 at 11:03 AM, Razvan Cojocaru <p...@razie.com> wrote:
>>> I often find myself wishing I could build new combinations of traits at
>>> runtime and create an instance from them.
>
> What exactly do you mean by that? Something like an anonymous class? Do you
> imply that you don’t know the traits you want to mixin until you actually
> run?

Yup. It's surprisingly useful.

Run-time? Compile-time? What's the difference? It's all "computer
time". If you like all the uber type stuff, then cool. Make it so
the the compiler is available at run-time (in an easy fashion, yes I
use one of the numerous hacks out there to use the Scala compiler at
run-time) and have it do the incremental type-check magic. It's all
good.

--
Jim Powers

Dennis Haupt

unread,
Feb 9, 2011, 11:17:43 AM2/9/11
to Dennis Haupt, iv...@mojolly.com, scala...@googlegroups.com, p...@razie.com
wait...can't you do that in groovy? at least the delegate part is really easy...

can you combine scala and groovy? if yes, the problem might be solved already :)
i'll check that later

-------- Original-Nachricht --------
> Datum: Wed, 09 Feb 2011 17:14:30 +0100
> Von: "Dennis Haupt" <h-s...@gmx.de>
> An: "Razvan Cojocaru" <p...@razie.com>, scala...@googlegroups.com, iv...@mojolly.com
> Betreff: Re: RE: Re: [scala-user] benefit of dynamic typing?

Vlad Patryshev

unread,
Feb 9, 2011, 11:53:53 AM2/9/11
to Dennis Haupt, Volodymyr Kyrychenko, scala...@googlegroups.com
Right... but I believe null is not a timebomb, but some kind of dynamic type. It is a pretty legitimate implementation of Option; the problem is that then all we do we do, often unknowingly, within a monad, and this makes what we do opaque to both us and the compiler; in explicit Option there's no way we would mix a pure value with a partial value.

2011/2/9 Dennis Haupt <h-s...@gmx.de>



--
Thanks,
-Vlad

√iktor Klang

unread,
Feb 9, 2011, 11:57:49 AM2/9/11
to Vlad Patryshev, Dennis Haupt, Volodymyr Kyrychenko, scala...@googlegroups.com
On Wed, Feb 9, 2011 at 5:53 PM, Vlad Patryshev <vpatr...@gmail.com> wrote:
Right... but I believe null is not a timebomb, but some kind of dynamic type. It is a pretty legitimate implementation of Option; the problem is that then all we do we do, often unknowingly, within a monad, and this makes what we do opaque to both us and the compiler; in explicit Option there's no way we would mix a pure value with a partial value.

Yet again we must listen to Tony: http://lambda-the-ultimate.org/node/3186
 



--
Viktor Klang,
Code Connoisseur
Work:   Scalable Solutions
Code:   github.com/viktorklang
Follow: twitter.com/viktorklang
Read:   klangism.tumblr.com

Jim Powers

unread,
Feb 9, 2011, 12:11:05 PM2/9/11
to scala...@googlegroups.com
On Wed, Feb 9, 2011 at 11:57 AM, √iktor Klang <viktor...@gmail.com> wrote:
> On Wed, Feb 9, 2011 at 5:53 PM, Vlad Patryshev <vpatr...@gmail.com> wrote:
>>
>> Right... but I believe null is not a timebomb, but some kind of dynamic
>> type. It is a pretty legitimate implementation of Option; the problem is
>> that then all we do we do, often unknowingly, within a monad, and this makes
>> what we do opaque to both us and the compiler; in explicit Option there's no
>> way we would mix a pure value with a partial value.
>
> Yet again we must listen to Tony: http://lambda-the-ultimate.org/node/3186

Although Tony Hoare's sentiments are laudable, they primarily stem
from the chaos "NULL" references cause in languages like
C/C++/Pascal/etc. where there is little abstraction of the machine in
question and the runtime is impotent to always "safely" handle "null"
pointers, or pointers into arbitrary memory for that matter. Java's
null is about as harmless as Lisp's nil (or Scala's None).

--
Jim Powers

Razvan Cojocaru

unread,
Feb 9, 2011, 12:22:37 PM2/9/11
to Dennis Haupt, scala...@googlegroups.com, iv...@mojolly.com
I don't see why you have to mix that in... in this particular case, just pipe the object through a ToUpperCase filter - the trait doesn't add anything, since it's applied to this particular instance. Also, these dynamically mixed in traits must be able to be mixed into anything and provide valuable functionality...don't see how

Basically dynamic wiring of the objects or flow or whathaveyou may make sense but building new types at runtime - I still don't see how arbitrarily mixing in traits *at runtime* can amount to something useful... I hear you but I don't see it. Anyone has an example?

Runtime vs compiletime - I'm not there when the program runs, that's the difference :) so that "you screwed up" exception at 2am ain't that useful.

Hey, I'm not arguing that it's completely useless - I don't see a good example. I haven't seen a good example so far, just constant mentions that there are...

Cheers.

Ittay Dror

unread,
Feb 9, 2011, 10:09:45 AM2/9/11
to Randall R Schulz, scala...@googlegroups.com

Randall R Schulz wrote:
> On Tuesday February 8 2011, Ittay Dror wrote:
>> ... The dynamic languages are more oriented
>> towards dealing with untyped data.
> There is no such thing as "untyped data."

correction: dynamic languages are more oriented at dealing with
attribute keys as method names.


Ittay
>
>> Ittay
>
> Randall Schulz

Ivan Porto Carrero

unread,
Feb 9, 2011, 4:03:40 PM2/9/11
to Razvan Cojocaru, Dennis Haupt, scala...@googlegroups.com
Most of my remarks stem from building DSL's.

Hosting the compiler like what scalate does?  then I'll get big bursts in my memory usage and cpu usage for no good reason and because java doesn't know how to manage it's own memory growth/shrinkage I have to guestimate what the amount of memory is my application might be using, if that app is under load I'd lose my meta programming bits and pieces and get out of memory exceptions instead.

Let's say I have a library but 1 part is left to be defined by the end user of my library. He needs to be able to keep state but I don't want him to see the entire interface of the class he's building.
In some cases (not all because you can pass it in as a callback object) it might make conceptually more sense to mix in the meta trait in the build method of the builder object. All of this has only one goal, the way the code is expressed by the end user of my library.

Another case is I may have a system that sends messages to some aggregator. those messages are composed of other messages and there is a multitude of combinations possible. The combinations of those messages might be defined in traits in the aggregator so it would be great if we could get the aggregator to then start combining those objects. These messages need to be materialised as an actual type at some point because they need some form of behaviour or they need to be passed in to some method that expects a certain type and so on. (100 traits => that's a lot of pattern matches) Using a code generation technique would require a significantly higher amount of time and effort than meta programming this. I can take this example further and have the message senders expose a jar with the traits they define that I can download and dynamically load in my aggregator application. At that point the traits were previously unknown but are known now. This is perfectly possible (I'm not saying you want to do that in all cases but in some cases it's actually useful)

Meta-programming is actually an extremely useful bit once you know how to properly leverage it in maintainable way.
The type level programming I'm learning more and more about might help to a certain degree but it won't cater to all cases or would add a bunch of boilerplate to define the compiler contracts.

Yes I can run groovy, ruby, rhino to get that bit going but why bother with static typing at all then?
As an aside the only way the compiler actually ensures program correctness is by utilising the scala type system to its fullest otherwise you're just pretending. While it might catch fairly trivial errors like wrong casts there wouldn't be an InvalidCastException if everything could be verified prior to runtime. Now if everything is defined in compiler contracts by using the type system you can get the compiler to actually verify your intent instead of just working out if you've put the right stickers on everything (.asInstanceOf[Sticker])

So all I'm saying is that the big brains who are driving scala development are doing a great job at building the-language-I-always-wanted-and-only-discovered-last-year; although it would be great if there was some statically typed meta-programming capabilities sprinkled in, I'm sure it's possible, there are huge time savings involved in that and it's the only thing that I keep wishing I had available in my toolbox. (well that and reified generics)

Allow me to take a stab at making the distinction between strong/weak typed and dynamic/statically typed a bit more clear because people seem to get that part wrong. The main differentiator to look out for is something like this:

(dynamic but strongly typed)
a = 1
a + "1" => error no explicit conversion exists (strong typed but dynamically)
a = "1" => works because dynamically typed but still strong but no static compiler checks

now in C (weakly but statically typed) you can something along these lines:

int i = 1;
i + "1"  => c will now try to guess what you are trying to achieve (weakly typed, but static) but no compiler error just an unexpected run-time result
i = "1" => compiler error (statically typed)


----


Met vriendelijke groeten - Best regards - Salutations

Ivan Porto Carrero



Volodymyr Kyrychenko

unread,
Feb 9, 2011, 7:54:44 PM2/9/11
to scala...@googlegroups.com
Dennis Haupt wrote:
> null is simpler, but can become time bomb and explode at a random time when you actually try to access the object which makes it more difficult to find the source of the problem. explicitly checking as soon as possible acts as a guard against this.

Yes it could. But if your interface is dynamically build against amazon
WSDL for instance - what could you possibly do to disarm it? Whatever
you will do with compilation checks (for instance using some sort of
WSDLC at compile time) will not gona help you if amazon alter the services.

>> Another reason that only part (which is not the one you're using) could
>> be altered - for the dynamic language it's fine. Imaging if
>> bash-scripting was statically typed. In this case scripts should be
>> "compiled" against very particular versions of utilities. If something
>> changes in 'ls' - go 'recompile' your scripts. For the small scripting
>> purposes or integration purposes dynamic typing is good not because it
>> has some particular advantages over static typing, but because static
>> typing has disadvantages in this case - too much checks those grant
>> nothing.
>
> i see. so basically, "dynamic typing" means "i know more than the compiler does."

Yes - a kinda.

> i thought about this. imho, a hybrid would be best.

Depends. If we're talking here about big projects - so the static
language with @dynamic part is best here, but if we're talking about
customization scripts/plugins/embedded parts - simple dynamic languages
rule, because it's easier to fix some javascript that does simple thing
and put it in MyCoolProgram/plugins directory possibly in already
started program, than start with big compilation process against
MyCoolProgram/libraries.

And another good example is E4X[1]. Nothing like this could be done with
static checks.

[1] http://en.wikipedia.org/wiki/ECMAScript_for_XML

signature.asc

Dennis Haupt

unread,
Feb 10, 2011, 5:59:30 AM2/10/11
to Volodymyr Kyrychenko, scala...@googlegroups.com

> Dennis Haupt wrote:
> > null is simpler, but can become time bomb and explode at a random time
> when you actually try to access the object which makes it more difficult to
> find the source of the problem. explicitly checking as soon as possible
> acts as a guard against this.
>
> Yes it could. But if your interface is dynamically build against amazon
> WSDL for instance - what could you possibly do to disarm it? Whatever
> you will do with compilation checks (for instance using some sort of
> WSDLC at compile time) will not gona help you if amazon alter the
> services.

this problem is independent of the used type system. once you leave the compiler's realm, static typing does not apply anymore.

Reply all
Reply to author
Forward
0 new messages