Hacker News new | ask | show | jobs
by afandian 4634 days ago
(Note I am not the GP)

This feels weird. I have a gut reaction to this, and it's conflicted. Perhaps the same feeling `redbad` has, perhaps not.

On the one hand, I feel like this is a million miles away from the Go I know and love. I've used Ruby, Python, C#, Java, C, Obj-C, JavaScript etc in the past. In terms of mental processes, the way I write go is closest the way I would write C or Java.

I write tests that do the same thing as this, that have pre and post conditions and assertions and explanations in comments. The whole point of static type systems, surely, is that you represent things (constraints, state, possible values, etc) in code rather than comments and rely on the language to enforce them rather than the next developer to read your comments, so the explosions happen at compile time rather than production. So, by that token, this kind of DSL seems like a step in the direction of static typing, rather than the other way round.

I've not looked at the source, but the line `Expect(scoreKeeper.Stats["Manning"]["Touchdowns"]).To(Equal(1))` might use all kinds of clever closure stuff but ultimately wouldn't compile if the right interfaces weren't satisfied. Unless there are `interface{}`s all over the place, which would be regrettable.

On the surface, this seems like a step toward Ruby with its endless DSLs which feels like the antithesis of static typing. That naturally feels a bit weird and a bit of a culture lurch. But perhaps the DSLs are closer to those of Scala than Ruby.

Both feelings I get are fuzzy and not particularly arguable, but I think peoples' relationships with languages are very personal and that's such a fundamental quality of the PL landscape that it's worth not discounting.

2 comments

DSLs are not the antithesis of static typing. Beware of using the word strong when discussing type classification. That word is highly muddled and doesn't mean the same thing to everyone.

Haskell, for instance, is statically typed and does DSLs very very well. In fact, you use the type system as an augmentor of the DSL: it sets up the rules for how to embed the DSL in the code base itself. And it disallows a class of programs which would not work at all.

The right way to view types is that they allow a far richer description of what your code is doing because you can discriminate values on their types.

And before you lynch me: my professional work job is in Erlang which is a dynamically typed language.

You're right. Strong and static occur so often together (Go is both strong and static (mostly), for example) that I fell into the trap of glomming them both together. I've edited my post.

EDIT: And when I said 'the antithesis of static typing' I meant purely in the Ruby context, which is famous for its DSLs.

(context: i've been working mainly with python, and have almost no experience with go)

My initial reaction to the example was that it looked like something that could be easily unit-tested, without the added layer of BDD over the top. But that's probably just a symptom of the example appearing as something that would be simple to build and test.

E.g. in python i'd translate `Expect(scoreKeeper.Stats["Manning"]["Touchdowns"]).To(Equal(1))` to `assert scoreKeeper.Stats["Manning"]["Touchdowns"] == 1` which is essentially the same, but only uses one bit of machinery (assert) rather than three.

That said, the more ways to test things the merrier. I think if you are interested in testing larger chunks of functionality / user-facing bits of behaviour rather than invariants of the building blocks of your program, then perhaps BDD starts to look more appealing, so the two approaches seems complementary.

Having an expressive static type system is again complementary, as that prevents you from making many trivial errors, and you just have to test for the remaining ones that the type system cannot express. (i miss that in python)

after a little dig through the code, it looks like "EXPECT foo TO EQUAL barr" translates as

https://github.com/onsi/gomega/blob/master/gomega.go#L15 https://github.com/onsi/gomega/blob/master/actual.go#L27 https://github.com/onsi/gomega/blob/master/actual.go#L48 https://github.com/onsi/gomega/blob/master/matchers.go#L7 https://github.com/onsi/gomega/blob/master/matchers/equal_ma...

so there's lots of `interface{}`s and reflection and so on

Unless I'm missing something, assert scoreKeeper.Stats["Manning"]["Touchdowns"] == 1 is not the same unless in python you have some magic reflection. The output you get from that is just pass/fail. The output you get from the matcher method is the expected and actual values in a much nicer error message.
you (& afandian) make a good point, and i believe that's roughly how py.test does it, by rewriting the code of test modules before running tests. which would be fair to call magic.

http://pytest.org/latest/assert.html#advanced-assertion-intr...

Go already has the equivalent of assert, this new library is a reaction to it not being [insert problem here] enough.

The equivalent in Python would actually be building up a whole AST-style object tree full of expressions, and then executing it.