Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
A statically typed language I'd actually want to use (alexgaynor.net)
33 points by andybak on Nov 5, 2010 | hide | past | favorite | 50 comments


At this point in computing history, your language needs a stronger raison d'être than "Python isn't statically typed, and C++ has awkward syntax!"; especially considering that 99% of all new languages never get off the ground. I'm virtually certain that there's something out there that fits the bill.

If not, contribute to something that gets close. Go, Scala, Haskell; whatever works. [Obviously, I do realize that building compilers/interpreters/parsers/etc. can be fun: if that's the point, disregard this.]


I'm not sure if that's true. While newer languages like python and ruby have taken the desktop app and web app arena by storm, most system/embedded level stuff is still done in C/C++. The usual arguments for this are that

A) The language gives you more control over memory management so you can squeeze as much performance out of every cycle.

B) There's a ton of existing libraries and legacy code in these languages. (Arguably one of the only reasons C++ gained any sort of traction was because of its advertised compatibility with C)

We've put up with the "shortcomings" of C (most programmers learned or think in OOP) and C++ (abundance of so-called gotchas and quirky areas of the language, Alan Kay's famous quote about C++'s OOP) and it still leaves much to be desired in my opinion. Java was an interesting development, but its GC disqualifies it for many systems or high-performance programming until recently. I don't have much experience with obj-c but it looks like another contender in this space as well.

There does seem to be a desire for a true "heir" to C as evidenced by D, Google's Go, and Mozilla's Rust. In fact, I'd be happy if someone just took the Java language and stripped out the GC instead of trying to restrict myself to a "safe" subset of C++.

I'm rooting for all of these projects because I'd love to see some of of the benefits of modern programming language theory brought to this sector of programming. This is an area where when there's competition everybody wins.


http://www.bitc-lang.org/ http://www.ats-lang.org/

Those might show promise as nice languages with speed comparable to C.


take a look at cyclone also http://cyclone.thelanguage.org/


His example is also completely unconvincing. I just don't see the problem he is trying to solve here. Unless you take the absence of static typing as a problem.

In general, new type systems should start with a good problem definition: e.g. what of errors would you like to prevent, and do those problems really occur? Then design a type system, and see if its costs (there is no free lunch) justify the gains. I think the big successes of dynamically typed languages such as Python point out a problem with the C/Java/C++ type systems: they fail to answer especially the latter question.

Finally, why a new language?! Build it on top of the type annotations in Python 3: http://www.python.org/dev/peps/pep-3107/

BTW I'm all for statically typed languages, if well done, and am a huge fan of Haskell


The problem with python is the lack of speed.


Also: No tail-call optimization, lack of a separate compile-time phase / static metaprogramming, strictly class-based / single-dispatch OO, etc.


> At this point in computing history, your language needs a stronger raison d'être than "Python isn't statically typed, and C++ has awkward syntax!"

True, but for all the rapid development in programming languages at the moment, we still don't actually have (AFAIK) a general purpose programming language that has simple, clean syntax à la Python, a static type system that covers all the basics but doesn't get too clever/complicated for everyday use, and good performance.

This always seems strange to me, given that all the necessary ingredients are widely available in other languages and I see no inherent difficulty in combining them. I suppose industrial forces already have "good enough" languages and academic forces are more interested in pushing the frontiers in languages like Haskell. That probably doesn't leave a lot of people with the required skills, time and inclination to work on a solid, practical, boring tool that just gets the job done a bit better than anything we have today but without trying to somehow reshape the entire programming industry and become the Next Big Thing.


SML/Ocaml:

- Rapid development

- Clean syntax

- Static type system

- Good performance

- Practical, not about pushing boundaries

SML especially, is a very stable, simple, and well thought out language.


The trouble is, I would love to have a language with properly controlled side effects and the basic functional goodies, but for real world use I'm not aware of any functional language that doesn't also make something basic much harder than imperative languages do.

If I could have a language with the functional toys of an ML or a Haskell, but where the impure side of things was as easy to write as the pure computations, that would be great. But for that to happen, I suspect there needs to be a dramatic shift in the way effectful code is written, in the same way that type inference practically eliminated all the syntactic overheads we might otherwise have assumed were necessary with a static type system.

I've seen a lot of research in this area, and there's huge potential in some of the ideas being tried out in languages like Haskell, but to my knowledge no-one has really hit anywhere near the sweet spot I'm looking for in a production language yet.


[...] where the impure side of things was as easy to write as the pure computations, that would be great.

From your post, I'm going to assume that you haven't used the languages I'm talking about; sorry if I misread that. SML/Ocaml/F# are not purely functional languages, so side effects work just like you'd expect coming from C/Python/etc. The language encourages functional programming (for example, variables are immutable by default), but imperative code is far from difficult to write. I highly recommend you try one of these languages. They may just be what your looking for.


I have some experience with both SML and OCaml, though it is quite limited.

Perhaps it's either my background writing a lot of fairly mathematical code or simply my own ignorance, but I always found little things like having to distinguish * and *. operators in OCaml rather awkward. Granted, it beats M.times(a).plus(b), but it's the sort of slightly clunky blemish that puts me off, and it betrays a certain lack of power in the underlying model. (Haskell almost has the opposite problem, with a type system that seems able to do almost anything, but also having all the complexity that inherently comes with that.)


Type classes may come to OCaml one day. That would solve it.


AliceML adds distributed programming, constraint programming, lazy evaluation, plus more.

http://www.ps.uni-saarland.de/alice/


While AliceML is quite nice, the main advantage that SML has over the other major ML-family languages is, IMHO, that it's simple, well-defined, and has several fairly-compatible and high quality implementations.


Yep. Alice is a superset of SML. I have them both running under Emacs and I have to do a double take when something doesn't work in Alice, just to discover it was SMLNJ that I was running.


haXe seems to come within inches of your idea:

Inferred static compilation for multiple VM/source targets with a "trapdoor" into the target's dynamic typesystem. JS-like syntax. Macro system(still in development but usable). Compiles to reasonably performant C++, although matching hand-written C++ performance is not a goal.

I have been using it for several years now with the Flash/JS targets.


All of them suck: Go doesn't have parametric polymorphism and feels half-baked, Scala is not compiled to machine code and is awkward in his own unique way, and for Haskell you need a PhD and the compiler's behavior is not at all transparent and comes back to haunt you.

I've stopped searching for the perfect language some time ago and just don't care anymore.


Learn an ML dialect and be happy.


I'm hoping to see a fortune cookie that says that, someday.

("Learn an ML dialect and be happy in bed"?)


You don't need a degree to use Haskell. Just because it's a research language doesn't mean it requires a lot of research to understand or use.


It was a figurative statement, and you can't really say that Haskell doesn't have a steep learning curve.

Every language sucks in one way or another; and when I'm saying "language" I'm also talking about the implementations since you can't really separate them when working.

It's funny that the fastest way to get downvotes on discussion boards (other than saying something really stupid) is to criticize technologies.


C# is a statically typed language that gets a lot right (and not coincidentally also borrows a ton from Python). As mainstream languages go it's probably the best out there; too bad the Mono compiler is usually a version behind and the VM does not have competitive performance with either Windows CLR or Linux JVM.


Except C#'s still quite verbose. Doubly so if you heavily use generics and functional programming. You just aren't as free in the style of code that works.

For one sample point, I rewrote one of FreeSWITCH's C modules in C# and F#. The F# version had 1/20th the number of type annotations.


The c# version is pretty concise. And since 3.0 with implicitly typed local variables, its gotten less verbose.

var result = seq.Where(a=>a %3==0).Select(a=>a*a);


Yea, but try moving the predicate to a local function, and you get:

Func<int, bool> pred = a => a %3 == 0.

Mix in more complex types (say a dictionary with a tuple in it), and it starts getting pretty verbose.


Talking about static typing without investigating something like Haskell (as mentioned by others) seems limiting, particularly since Guido picked up a couple of things from Haskell like the list comprehensions presented in this post.

And then you'll discover that Haskell's type system is limited as well. Learn some Qi - http://www.lambdassociates.org/qilisp.htm.


Those who don't know type inference are destined to reinvent it ... badly.


True, but Matz didn't know a lot of things about programming languages and luckily for me, he didn't care and reinvented them anyways.


Especially as the upcoming BitC language seems to have sound _and_ complete type inference http://en.wikipedia.org/wiki/BitC


Haskell could, trivially, do the first example shorter than python.


I'm no Haskell expert, but it's a couple chars shorter AND solves the premise of the entire post.

    [x*x | x <- s, x `mod` 3 == 0]
And the function definition doesn't need all of the type clutter:

    let playWithSeq s = [x*x | x <- s, x `mod` 3 == 0]
    
    playWithSeq [0..10]
    -- [0,9,36,81]


Just curious: would anyone care to show me how something like that would look in Clojure?


    (for [x s :when (== 0 (mod x 3))] (* x x))


why do you use ==? You should use =.


I use `==` when I know that I'm comparing numbers.


I'd prefer map and filter. But then, I don't like list-comprehensions in Haskell.


Yeah, but then there wouldn't be anything to blog about.


C++ is statically typed? I guess if you omit the five cast operators and don't throw exceptions and don't allocate any heap, you can sort of reason about type safety. Sort of.


It's statically typed (variables have types), manifestly typed (you have to declare them), but not type-safe (won't treat values of one type as if they're of another).


That seems to be the worst of all words.


I use C++, and I have a variety of utility functions defined. To do his task, first I already would have the following defined:

  template <class Pred, class Sequence>
  Sequence filter(Pred p, const Sequence& in)
  {
    Sequence out; 
    for (typename Sequence::const_iterator i = in.begin(); i != in.end(); ++i) {
      if (p(*i)) {
        out.insert(out.end(), *i);
      }
    }
    return out;
  }
And then I would do:

  bool is_div3(const int n)
  {
    return n % 3;
  }

  // in another scope

  result = filter(is_div3, seq);
It's not how most people use C++, but my recent work has involved manipulating parse trees. I find the most natural way to do this is recursively using functional techniques, so I've built up a small set of functionaly inspired utility functions (https://github.com/scotts/cellgen/blob/master/src/utility.h). C++0x will let me use an anonymous function instead of having to define a function (or function object) for my predicate.


Looks like scala to me:

  def playwith_seq[A] (seq : Iterable[A]) : List[A]
    for (x <- seq if x % 3 == 0) yield x * x


I really wish that Fantom http://fantom.org/ received more love.


Can you elaborate on why? What is it you like about Fantom? Why should I check it out?


Just found: http://fantom.org/doc/docIntro/WhyFantom.html

Nice language syntax wise, seems pretty nice. Prime unique feature is the ability to run on a JVM or the .NET runtime. It also provides a base layer of objects to replace java.io/util etc.

I'm not to clear if it maintains JVM or .NET interoperability. That would be interesting if it could call both JVM and .NET code.


My comment was about the fact that I'd like to commit to it (for production work), but as a player not getting much love from devs, I cannot bring myself to do that... yet.

Fantom would bring _me_ most of jRuby's benefits, but with familiar syntax for non-Ruby devs, with the addition of optional JavaScript runtimes; thus providing one language for front and back ends. I also simply like the "feel" of Fantom.

It kind of melds the best bits of Java, Ruby, Scala, and C#, I guess. And it rejects the bad.

The fact that Stephen Colebourne likes it is a plus, as I trust his judgement in such matters.

http://www.artima.com/lejava/articles/javaone_2010_the_next_...

For ref, here's the Why Fantom? page http://fantom.org/doc/docIntro/WhyFantom.html

Without using it in full fury, I can't argue a defensible "must try" validation, but there's more to like in Fantom, for me, than anything else I see at the moment.


OOC, assuming `x` implements `List<Int>` (sorry for syntax mistakes, don't have a compiler here). So yes - generics and type safety included:

    x = x filter(func (i:Int)->Bool {i%3==0}) map(func (i:Int)->Int {i*i})
Edit: missed the multiplication


"A good example is "give me the square of all the items in this sequence who are divisible by 3""

A good example? Really? You get paid to write stuff like that? Because I don't. If you're going to promote a language as a better solution, try solving real problems.

What happens when there's a string in the sequence? The C++ example solved that, why didn't your code?


Haskell also would solve it, by outlawing the occurence of strings at compile time.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: