The Artima Developer Community
Sponsored Link

Weblogs Forum
Static Versus Dynamic Attitude

22 replies on 2 pages. Most recent reply: Feb 21, 2005 9:45 PM by Steven Shaw

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 | » ]
Bill Venners

Posts: 2284
Nickname: bv
Registered: Jan, 2002

Static Versus Dynamic Attitude (View in Weblogs)
Posted: Feb 9, 2005 12:39 AM
Reply to this message Reply
Summary
To what extent does the mindset encouraged by a language and its surrounding culture influence people's perceived productivity when they use that language? In this weblog post, I take a look at this question in the context of the static versus dynamic typing debate.
Advertisement

There has been much debate concerning the relative merits of static and dynamic languages. Dynamic language enthusiasts feel they are far more productive when using languages such as Smalltalk, Python, and Ruby compared to static languages like Java or C++. Static language enthusiasts feel that although dynamic languages are great for quickly building a small prototype, languages such as Java and C++ are better suited to the job of building large, robust systems. I recently noticed that in my own day-to-day programming with Java and Python, I approach programming with a different mindset depending upon the language I'm using. I began to wonder to what extent the mindset encouraged by a language and its surrounding culture influences people's perceived productivity when they use that language.

Refactoring JSPs to Poor Man's Struts

A year ago at Artima I had a large number of JSPs that weren't organized in an model-view-controller (MVC) architecture. In these JSPs, the business logic was mixed with logic responsible for generating the HTML view. I wanted to start making incremental improvements to these JSPs by refactoring each JSP into an MVC architecture whenever I needed to make a change to that JSP. I didn't want to change any existing URLs, and wasn't pleased with the frameworks I investigated such as Struts and WebWork, so I adopted an interim approach I called "poor man's struts."

For each JSP I refactored to the poor man's struts architecture, I created a Page class (the controller) with a static process method. I moved the business logic from the JSP into the process method, and called the process method from the top of the JSP, like this:

// Imagine this is the top of a JSP,...
ExamplePage.Context context = ExamplePage.process(request, response, session);

After executing the business logic, the process method returned a context object filled with objects that the remainder of the JSP needed to render the page. Because the business logic often included explicit redirects, I decided to let the context object indicate whether or not the process method had already redirected the client. If the so, the JSP simply returned:

// Imagine this is the top of a JSP,...
ExamplePage.Context context = ExamplePage.process(request, response, session);

if (context.isRedirected()) {
    return;
}
The remainder of the JSP, the view portion, usually depended on variables that were declared in the business logic portion. Now that the business logic had been moved to the process method, I needed to redeclare those variables. Therefore, I declared the missing variables next and initialized them with values and objects extracted from the context object, like this:
// Imagine this is the top of a JSP,...
ExamplePage.Context context = ExamplePage.process(request, response, session);

if (context.isRedirected()) {
    return;
}

long forumID = context.getForumID();
boolean reply = context.isReply();
String subject = context.getSubject();
String body = context.getBody();

The Context Classes

My insight into the different mindsets I adopt when using Java and Python became apparent to me when I was deciding how to return the information and objects from the process method to the JSP. In many web MVC frameworks, this information is moved by placing the information in a context object, whose sole purpose in life is to move the information from the controller to whatever entity is rendering the view. Similarly, in the case of poor man's struts, the process method populates a context object and returns it to the JSP. Because all poor man's struts context objects would need to indicate to the JSP whether or not the process method had performed a redirect, I created ControllerContext, a superclass extended by all context classes:
public class ControllerContext {

    private boolean redirected;

    public ControllerContext(boolean redirected) {
        this.redirected = redirected;
    }

    public boolean isRedirected() {
        return redirected;
    }
}

For each Page class, I created a nested class called Context. The constructor of this class accepted a boolean redirected flag and a parameter for each value or object needed by the JSP. Here's an example:

// Declared inside the ExamplePage controller class

public static class Context extends ControllerContext {

    private long forumID;
    private boolean reply;
    private String subject;
    private String body;

    public Context(boolean redirected, long forumID, boolean reply,
                    String subject, String body) {

        super(redirected);

        if (forumID < 0) {
            throw new IllegalArgumentException();
        }
        if (subject == null || body == null) {
            throw new NullPointerException();
        }

        this.forumID = forumID;
        this.reply = reply;
        this.subject = subject;
        this.body = body;
    }

    public long getForumID() {
        return forumID;
    }

    public boolean isReply() {
        return reply;
    }

    public String getSubject() {
        return subject;
    }

    public String getBody() {
        return body;
    }
}

Attitudes on Multi-Valued Returns

The context object is a vehicle that enables the process method to return multiple values to the JSP. In several Java MVC frameworks, the context object is essentially a Map. The controller places objects into the context Map identified by named keys. Had I taken this approach in poor man's struts, for example, the process method of ExamplePage could have placed the subject string "A Tale of Two Cities" into the Map with the key "subject". I rejected this approach primarily because I felt creating a specific Context class for each controller would allow me to employ the type system to enforce constraints. The ControllerContext superclass, for example, enforces that all context objects supply a boolean redirected value. The ExamplePage.Context subclass enforces that ExamplePage.process always provides a non-negative forumID. My theory was that such constraint checking would help me achieve robust code.

In practice, however, I found I was always in a hurry when I refactored a JSP to poor man's struts, because I only performed this kind of refactoring when I otherwise had some enhancement or bug fix to make to the JSP. I also found that this approach to the context object required a lot of code. To speed up the process, I wrote a Python script that, given a simple list of types and variable names, generated much of the needed Java code. The Python script did not generate any validation of input parameters in the Context constructor. I needed to write those by hand, and I discovered that I rarely felt it worth the time to do so.

Given this experience, I ultimately decided that the added type safety wasn't really worth the extra effort it required in this situation. In our new MVC architecture, the controllers return essentially a Map context, and we enforce constraints with unit tests. The wierd thing is that I realized that if I had been designing poor man's struts in Python, I probably wouldn't have thought twice about just returning all that information in a tuple, as in:

(redirected, forumID, reply, subject, body) = ExamplePage.process(req, resp, session)

From a safety perspective, a tuple seems even more error prone than a Map, because I have to get the order correct on both sides, not just the names. If the thirteenth element in the tuple is a message ID, then I have to make sure the thirteenth element in both the return and assignment tuples is messageID. While order is generally random, names of keys and variables are usually similar, such as:

String subject = context.get("subject");
In Java, the multi-valued approach equivalent to Python's tuple would be toss everything into an array of Object and pull it out by index on the other side. I would never do that in Java, but I don't hesitate to do it in Python. Why?

One reason is that Python supports this multi-valued return technique better in its syntax than Java, but I realized that the availability of syntax isn't the main reason I do it in Python. The main reason is that's the way it's usually done in Python. By contrast, that's not the way it's usually done in Java. The cultures are different. The culture that guided the design of a language influences my attitudes and mindset when I use the language. The Java culture encourages me to build solid bricks that can be combined to build large, dependable systems. The Python culture encourages me to glide smoothly and quickly to a solution.

This realization got me wondering, to what extent is this perceived increase in productivity with languages such as Python, Ruby, and Smalltalk due to the culture of those communities, and the mindset that the culture engenders in programmers, versus the actual languages themselves? Do you find yourself performing acts with reckless abandon in one language that would make you feel guilty to do in another? How easily can you switch mindsets when you switch languages? Do you find yourself fighting the mindset in one language, and feeling at home in another? What is the real source of the differences in the static versus dynamic language debate?


Girts Kalnins

Posts: 23
Nickname: smejmoon
Registered: May, 2003

Re: Static Versus Dynamic Attitude Posted: Feb 9, 2005 2:55 AM
Reply to this message Reply
I don't see here static versus dynamic. Java loses type information too, when you put everything in Object array ?

It's just easier to write in python, when we understand that comma [,] is a tuple operator.


But I would not return 5 values with tuple, i would put them into dict[ionary]. And when things get important enough, you can subclass this dictionary and add verification or whatever is important.

Todd Siegel

Posts: 7
Nickname: tsiegel
Registered: Mar, 2004

Re: Static Versus Dynamic Attitude Posted: Feb 9, 2005 4:40 AM
Reply to this message Reply
> How easily can you switch mindsets when you
> switch languages?

I guess I don't fully understand the Python mindset. Professionally, I have been doing Java for so long that, perhaps, this is the only mindset I have. But I'd like to think I am using good, general OO practices and good, general coding practices rather than anything that is Java specific. I would have solved your problem in Python using something like the Context type rather than a tuple. It just seems right to me.

I found when I applied my "Java mindset" to Python I still ended up with very clean and concise code.

Alex Blewitt

Posts: 44
Nickname: alblue
Registered: Apr, 2003

Re: Static Versus Dynamic Attitude Posted: Feb 9, 2005 4:42 AM
Reply to this message Reply
There's a lot to say that different programming languages will allow you to do things in different ways. For example, functional programming languages will let you do much more list-processing in a far easier and faster way than procedural programming languages. Declarative languages are different still.

Knowing about lots of different styles of language (and not just different language dialects) can help you see other ways of doing things. For example, if you know about Python's ease of use with lists, then you might be tempted to do extra processing with Lists in Java. Or, if you're au-fait with the iterator-based constructs (e.g. xrange) you might be tempted to use Java's Iterator for that purpose.

Of course, if a language makes it easy to do something, it's more likely that you will use that feature in that language over another. For example, proxying in Objective C (and Smalltalk) is incredibly easy, with the result it's used a lot more often than in Java. (You can do aspect-oriented programming in Smalltalk and Objective C with a single class wrapping the other; there's no need for frameworks such as AspectJ)

Whether something is compiled or interpreted largely confuses the issue when you're comparing languages with functional and non-functional aspects (or object and non-object aspects). Granted, there's a difference in how long it takes to get the first script written (a dynamic language, because of its interpreted nature, is easier to run and debug) -- but it's not a property of the language itself; it's a property of the compiler/interpreter. There's no reason that a Java interpreter couldn't exist for doing simple method calls; see BeanShell for an example.

Whether something has static or dynamic /typing/ is another issue; there's strengths and weaknesses of both. Less typing is certainly an argument for dynamic/untyped languages; but on the flip-side, refactoring isn't as easy (and thus less well-supported). That's not to say it can't happen -- the Smalltalk refactoring browser showed that -- but it's more common amongst the statically typed languages, since it can help to narrow the search down. (Refactoring support in JSPs, and in particular, JSTL is pretty much non-existant due to the fact that JSTL is dynamically typed.)

It's also worth noting that some languages don't have/require type declarations, but are typed (e.g. Python), and others where everything is untyped (e.g. Rexx). You also have things the other way -- for example, Objective C can be both statically typed and dynamically typed in the same program. You can have variables that define X x = new X(), and then only send it 'x' messgaes; but you can also have ? x = new X(), and can send 'x' any message. (It's a run-time error if it doesn't exist).

So I don't think there's a clear winner based on type/untypes alone. What does make a difference is the supporting libraries and language constructs; for example, Python is excellent at list-processing (and to a lesser extent string-processing), Perl is excellent at string-processing, and Java is well suited for agile development (in an IDE like Eclipse).

You can even combine these ideas; for example, Cocoa apps on Mac OS X are (mostly) Objective C, but often have extension points that can be executed with Apple Script.

There's no reason that one product needs to be written in one language; witness JSP/JSTL and Servlets. Knowing the benefits of each and when to use a specific language is far more important than arguing which one is better ...

Rodrigo B. de Oliveira

Posts: 2
Nickname: bamboo
Registered: Feb, 2005

Re: Static Versus Dynamic Attitude Posted: Feb 9, 2005 7:07 AM
Reply to this message Reply
> The culture that guided the design of a language
> influences my attitudes and mindset when I
> use the language.

I feel that too but I wouldn't say this argument belongs to "Static x Dynamic" debate. I think it is totally possible to have the same pragmatic attitude in a static typed environment assuming there's a culture behind it encouraging such an attibute (and of course, the language doesn't get in the way).

Thanks for sharing,
Rodrigo

Bill Venners

Posts: 2284
Nickname: bv
Registered: Jan, 2002

Re: Static Versus Dynamic Attitude Posted: Feb 9, 2005 7:33 AM
Reply to this message Reply
> I don't see here static versus dynamic. Java loses type
> information too, when you put everything in Object array
> ?
>
True, but Java culture doesn't generally lead people in that direction. The way I felt this fit into the static versus dynamic debate is that I noticed that Java culture leads me in directions that required more time and code, whereas Python culture leads me in directions where things take less code and time. So I got to wondering how much the static versus dynamic debate about languages was really a debate about different cultures, and the mindsets they engender. I.e., to what extent is the question not "Which programming language is best suited for which kind of task?" but "Which mindset is best suited for which kind of task?"

Bruce Eckel

Posts: 875
Nickname: beckel
Registered: Jun, 2003

Re: Static Versus Dynamic Attitude Posted: Feb 9, 2005 10:21 AM
Reply to this message Reply
I posted the following here:
http://onthethought.blogspot.com/2005/02/static-versus-dynamic-attitude.html

I think your point about the language "leading you in a particular direction" is key. I've found that each language tends to make me think about doing things in a particular way, and they often seem like they actively prevent me from thinking about other possibilities. Witness the C++-ish influences on the designs in GoF.

But if I learn a new language that has a different way of thinking, then I can go back to a previous language and apply that way of thinking, just as you are now able to think about tuple-ish things in Java whereas it may not have occurred to you before. It's the beginning of a differentiation between saying "everything is an object" and "there are different kinds of objects."

On the other hand, your statement about the tuple reflects more of your static-mindedness: "From a safety perspective, a tuple seems even more error prone than a Map, because I have to get the order correct on both sides, not just the names." When you think about it as a Python tuple or a Java container of Object, your static-mind says "the compiler can't check it, so any object can go in any slot, and I could get it wrong." But if you realize that in both Java and Python (but not C++, which may be where the original roots of this "problem" lie), type checking also happens at run time, you realize that the first time you try to use one of these objects that you've put into the wrong slot, you'll find out about it.

I think the biggest problem when thinking about this is that static-mind is very deterministic and unforgiving, and says "if I can't find out about it at compile time, all is lost." In reality, you can only find out about some problems at compile time, anyway. Dynamic languages shift the discovery of problems more towards runtime. If you can accept that there are plenty of problems that can only ever be detected at runtime anyway, it's possible to look at this issue with a little more perspective, and to calm down the stridency of the static-mind a bit.

Isaac Gouy

Posts: 527
Nickname: igouy
Registered: Jul, 2003

Re: Static Versus Dynamic Attitude Posted: Feb 9, 2005 11:11 AM
Reply to this message Reply
> True, but Java culture doesn't generally lead people in
> that direction. The way I felt this fit into the static
> versus dynamic debate is that I noticed that Java culture
> leads me in directions that required more time and code,
> whereas Python culture leads me in directions where things
> take less code and time. So I got to wondering how much
> the static versus dynamic debate about languages was
> really a debate about different cultures, and the mindsets
> they engender. I.e., to what extent is the question not
> "Which programming language is best suited for which kind
> of task?" but "Which mindset is best suited for which kind
> of task?"

Maybe you're putting the cart before the horse - seems like the working practices we're labelling 'culture' are mostly ways to work within the constraints of a particular language.

Whenever you start to think of some Java problem as a general problem with static type checking, maybe rewrite it in Nice http://nice.sourceforge.net/

let boolean redirected, reply;
let long forumID;
let String subject, body;

(redirected, forumID, reply, subject, body) = ExamplePage.process(request,response,session);

Girts Kalnins

Posts: 23
Nickname: smejmoon
Registered: May, 2003

Re: Static Versus Dynamic Attitude Posted: Feb 9, 2005 11:41 AM
Reply to this message Reply
> "Which mindset is best suited for which kind of task?"

The difference I see here is that in Python you have some choices that you don't have in Java/C++ and other way around.

In python you can start it like:

1. (subject, body)
2. {'body': 'John', 'redirected': True, 'forumId': 123, 'subject': 'Ho!', 'reply': True}
3.

class Context(dict):
def __init__(self, *kwargs):
self.update(kwargs)
assert isinstance(self['forumID'], int)
assert self['forumID'] > 0


4. Then go on and replace asserts with your own exceptions, add methods..

On the other hand, if you have to deal with memory access, bit manipulation or write interfaces for other people, then some static thinking helps. And by static I mean caring about types, implementation, ease of use, when it's hard to change code.

Berco Beute

Posts: 72
Nickname: berco
Registered: Jan, 2002

Re: Static Versus Dynamic Attitude Posted: Feb 9, 2005 2:22 PM
Reply to this message Reply
I often find that it's not aspects such as dynamic vs. static that I weigh in the decision which language to use, but aspects such as:

- Is there a library for what I want to do?
- Is the offered functionality sufficient?
- Is the library well documented?
- Is the library easy to use?

Only when these things are equal for multiple languages I make a decision based on language features.

I guess I'm always on the lookout for the language/library that gives me the least hassle to get the job done. Comfort is the holy grail.

Berco

Bill Venners

Posts: 2284
Nickname: bv
Registered: Jan, 2002

Re: Static Versus Dynamic Attitude Posted: Feb 9, 2005 6:50 PM
Reply to this message Reply
> Maybe you're putting the cart before the horse - seems
> like the working practices we're labelling 'culture' are
> mostly ways to work within the constraints of a particular
> language.
>
Well, I think the horse is probably a philosophy that particular approaches to programming are good ways to achieve particular goals. For example, James Gosling seems to have subscribed to the belief that compile-time type safety is a good way to help programmers manage the complexity of large systems. This philosophy gallops around in the head of the programming language designer as he or she makes decisions about how to structure the language. The cart that follows the philosophy horse is the language itself, which is naturally designed to make it easy to program in the manner suggested by the philosophy.

The community that grows around the language is like a second cart that follows the first, language cart. This community would tend to subscribe to the same original philosophy, both because people of that mindset would be attracted to the language and because the language encourages them to think that way. There are usually a few people being dragged along behind the second cart who need to use the language, but don't really believe in the philosophy. But in general, it is unsurprising that the programmer culture that emerges fits the language and its designer's philosophy.

The point I attempt to make in the blog post is that it was primarily Java's philosophy that was speaking to me when I opted to create type safe Context classes, not the language. Java comes with a sense of right and wrong. Certain things are considered good practice, others bad. The question is to what extent is the static versus dynamic language debate about these competing notions of right and wrong that come from the differing philosophies?

> Whenever you start to think of some Java problem as a
> general problem with static type checking, maybe rewrite
> it in Nice.
>
I haven't tried Nice. I did try Groovy, but haven't used it for anything real (with one exception), because 1) it didn't seem ready for prime time yet, and 2) there was no refactoring support in IntelliJ. I was interestesd in using one of the JVM scripting languages in writing unit tests and possibly web MVC controllers. But after looking around a bit I ended up staying with Java because I wanted the refactoring support.

Howard Lovatt

Posts: 321
Nickname: hlovatt
Registered: Mar, 2003

Re: Static Versus Dynamic Attitude Posted: Feb 9, 2005 7:11 PM
Reply to this message Reply
I think it is mainly a mindset not the language, for example the multiple return types example you gave is easily handelled in Java using a Tuple API (e.g. as languages like Haskel do).

// Tuple API written once!
// J5 Only - Note class Tuple defines static classes and static methods
public class Tuple {
    // ... other Tuples
    public static class T5<E1,E2,E3,E4,E5> {
        public E1 e1;
        // ...
        public E5 e5;
        public T5(E1 e1,E2 e2,E3 e3,E4 e4,E5 e5) {
            this.e1=e1;
            // ...
            this.e5=e5;
        }
    }
    public static <E1,E2,E3,E4,E5> T5 t((E1 e1,E2 e2,E3 e3,E4 e4,E5 e5) {
        return new T5(e1,e2,e3,e4,e5);
    }
}
 
// Then for ExamplePage
import static Tuple.*; // Note static import
public class ExamplePage {
    public static T5 process(Request request,Response response,Session session) {
        // ...
        return t(redirected,forumID,reply,subject,body);
    }
}
 
// Then in use - using same names as original example
T5<Boolean,Boolean,Long,String,String> redirectedReplyForumIDSubjectBody=ExamplePage.process(request,response,session);
 
// Then when you want to refactor into a class
import static Tuple.*; // Note static import
public class Process extends T5<Boolean,Boolean,Long,String,String> {
    public Boolean getRedirected() { return e1; }
    // ...
    public String getBody() { return e5; }
    // Other methods
}

Bill Venners

Posts: 2284
Nickname: bv
Registered: Jan, 2002

Re: Static Versus Dynamic Attitude Posted: Feb 9, 2005 7:20 PM
Reply to this message Reply
> I often find that it's not aspects such as dynamic vs.
> static that I weigh in the decision which language to use,
> but aspects such as:
>
> - Is there a library for what I want to do?
> - Is the offered functionality sufficient?
> - Is the library well documented?
> - Is the library easy to use?
>
When I decided we needed to start over to a great extent here at Artima, I considered using Python or Ruby. If they could make even twice as productive as in Java, with good enough robustness, it would be worth it. But in the end I opted for Java for many non-language reasons: Frank and I know the most about Java, we have a lot of code that we wrote in Java that we wanted to continue to use, and Java has tons of libraries that we wanted to use: Hibernate, Lucene, Jini, Tomcat and lots of other Jakarta stuff, and all the Java APIs itself. Java has great refactoring IDEs, vibrant developer communities. I knew then that we were going to be primarily a Java shop for a long, long time.

Larry Bugbee

Posts: 13
Nickname: bugbee
Registered: Dec, 2004

Re: Static Versus Dynamic Attitude Posted: Feb 9, 2005 7:44 PM
Reply to this message Reply
Time is my most important criteria. Time to design, time to code, time to maintain, time to explain.

Please keep in mind that most of what I write are prototypes and POCs, so it is import to be able to get it working quickly, have the minimum invested should redesign be required, and be able to easily explain to others how it all works.

Python is generally my right choice, but sometimes Java. It depends.

Peter Booth

Posts: 62
Nickname: alohashirt
Registered: Aug, 2004

Re: Static Versus Dynamic Attitude Posted: Feb 9, 2005 9:20 PM
Reply to this message Reply
I think you are bang on the money. I have spent the past
four months working in an organization where all 400 developers use an interpreted, lisp based little language
to rapidly create tools that work with a quickly changing
business. I guess that I am about three times as productive as when writing Java and I find that Java seems restrictive,
binding, and verbose after this time away.

I think part of the problem is that many of us are in love
with complexity and Java makes complexity palatable (compared
to C or C++) and possible.

I also think there is a "Big Lie" surrounding OO that hinders us. OO has been the prevailing model for more than a dozen years yet doing OO seems to be beyond most programmers.

Strict typing for its own sake has no business value.
When is he last time a software user expressed any interest in it? Using Ruby or Python or ... gives us an excuse to
forget frameworks and "flexibility" (where flexibility == overengineered class hierarchies) and simply solve the problem at hand.

Whenever I forget software is soft I do myself a disservice.

Flat View: This topic has 22 replies on 2 pages [ 1  2 | » ]
Topic: The Sensible Trend of ScreenCasting Previous Topic   Next Topic Topic: The Diggins Friday Digest

Sponsored Links



Google
  Web Artima.com   

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