
Is your programming language unreasonable? - CmonDev
http://fsharpforfunandprofit.com/posts/is-your-language-unreasonable/
======
jfaucett
This is article actually has very little to do with any particular programming
language or language comparisons. I like how it logically builds up to each of
its conclusions which summed up are the following:

1\. Variables should not be allowed to change their type.

2\. Objects containing the same values should be equal by default.

3\. Comparing objects of different types is a compile-time error.

4\. Objects must always be initialized to a valid state. Not doing so is a
compile-time error.

5\. Once created, objects and collections must be immutable.

6\. No nulls allowed.

7\. Missing data or errors must be made explicit in the function signature.

I think the writer also provides a pretty practical definition of what it
means for a program to be "reasonable". Really nice job!

EDIT: I pasted the wrong list as dsp1234 pointed out :)

~~~
kyllo
_Once created, objects and collections must be immutable._

Collections I understand, but what's the point of immutable objects? If you're
eschewing mutability, why have objects at all? The whole point of objects is
to encapsulate mutable state, together with methods for mutating that state.

If you said _Once created, data structures must be immutable_ I would be more
inclined to agree.

~~~
tormeh
>The whole point of objects is to encapsulate mutable state, together with
methods for mutating that state.

Citation needed. I use my objects to hold immutable state with methods that
does not mutate that state.

~~~
kyllo
What do you gain from using objects in that way, as opposed to immutable
structs and functions?

~~~
tormeh
I program in Scala, so structs are not a thing (classes can extend/"inherit"
AnyVal to be allocated on the stack, though, I think). Functions are nice, but
from a pure syntax standpoint I often prefer methods because it limits the
parantheses. It's especially neat when the methods take no arguments, like
.toString.

But yeah, otherwise there's no difference, really.

------
richardwhiuk
The use of reasonable here, is, I'd argue, unreasonable and done for the
purpose of creating a click bait title.

They mean 'can we logically reason about programs written in this language'
rather than 'is the language a good choice' for solving problems.

~~~
pimlottc
> They mean 'can we logically reason about programs written in this language'
> rather than 'is the language a good choice' for solving problems.

At the risk of baiting flame, I find this distinction oddly amusing. If you
can't logically reason about programs written in a language, how is it ever a
good choice to use?

~~~
matthewmacleod
_If you can 't logically reason about programs written in a language, how is
it ever a good choice to use?_

You can never _perfectly_ logically reason about any program – your ability to
reason about a given program varies on a scale of 'easy to reason about' to
'difficult to reason about'.

While it's not always the case, it's easy to see that in some situations the
cost of making a language easier to reason about can outweigh the benefits.
The 'goodness' or otherwise of a language must factor in the difficult of
reasoning about it, but that itself is not a sufficient condition to describe
its quality.

------
rilita
I dislike javascript as much as the next guy, but the example in the article
is absurd:

function DoSomething (foo) { x = false}

var x = 2;

DoSomething(x);

var y = x - 1;

If you change "foo" to "x" then this works as expected. Who writes code that
looks like this anyway? Decent JS developers know that declarations elevate
themselves, and they also would not write code that looks like this.

This is like taking a couple words out of the middle of a sentence and
complaining because the meaning changing versus the whole overall sentence.

~~~
jfaucett
This example though perhaps not the best actually makes it pretty obvious that
if you have immutable objects and variables that cannot change their type you
already know that y will always be 1, since it is impossible for DoSomething
to change what x is bound to. So the example does illustrate the authors point
about being able to understand code without having to look at implementation
details.

~~~
rilita
That can easily be explained by the following example, which is much more
sensible:

var a_number = 10;

a_number = { blah: 10 };

var a_plus_two = a_number + 4;

Better yet you can simply say "Javascript does not have strict typing" and
point people at the wiki article on strict typing. This is clear and concise
as an explanation.

Showing confusing examples and saying "oh look this is horrible types can
change" does not make the point stronger.

The article uses a whole lot of words and examples to point out problems that
professional JS developers are aware of and work hard to avoid.

It also implies that such languages without strict typing are "unreasonable".
It's not unreasonable. It's that way on purpose.

------
failed_ideas
What is it with functional cheerleaders and their inflammatory language and
cherry picked arbitrary criteria?

------
dkarapetyan
I'm looking forward to day when instead of endlessly comparing languages
against each other everyone just shuts up and builds stuff so that merit of
your language choice can be judged by what can be built with it.

~~~
rdtsc
Before they shut up and build something they need to go pick their tools. This
is about picking the tools.

If we look at tools used in practice, we should be picking
C,C++,Java,C#,VB,Python. If we look at functional languages we should be
picking -- not sure, Erlang perhaps.

~~~
dkarapetyan
So are you going to pick F# now? None of the arguments in that post have
convinced me to switch.

~~~
rdtsc
I might. I really like F#, I was hesitant about the .NET and Microsoft
infrastructure. There was minimal interaction with it on the business side
(all Linux). Only recently have started playing with Mono. Now that .NET open
source, I might give it a second look!

~~~
dkarapetyan
Ah but you see your reasons are entirely pragmatic. You're worried about the
ecosystem and vendor lock-in. None of the arguments in the post even come
close to mentioning those things.

~~~
rdtsc
Ok you are right, I see your point.

I guess the assumption here is "all other things being equal" which is often
not the case. There are large team, difficulty in finding libraries, legacy
code, performance/testing/deploy-ability considerations.

------
AdeptusAquinas
I'm still missing it a little I think: the article says that if you remove a
bunch of flexibility, like mutable properties, then its harder to make
mistakes and your code is more predictable, right? But like the author
mentioned, if you follow good patterns and things like decent naming
conventions, and moreover know the language well enough to not make mistakes
around things like the purpose of .Equals, then you wont have problems and
wont be sacrificing anything either...right?

~~~
tome
You're absolutely right. You can indeed program in a "type safe way" in a "non
type safe" language. However, if you are going to do that, you may as well
have some compiler support too.

------
wampus
I like the article and think it makes some good points, but I can't help but
think the author is cheating a bit. If you really want to show the extent to
which a language can be inherently reasoned about, it seems like a slight-of-
hand to provide hints in the names.

Take a look at this snippet from example 6:

    
    
        // create a repository
        var repo = new CustomerRepository();
    
        // find a customer by id
        var customer = repo.GetById(42);
    

The fault is "I can't tell by looking at this code whether a null is returned
or not."

The improvement is this (in a language without nulls or exceptions):

    
    
        // create a repository
        var repo = new CustomerRepository();
    
        // find a customer by id and
        // return a CustomerOrError result
        var customerOrError = repo.GetById(42);
    

Aside from the comments and a change to the variable name, isn't this code
identical? The fact that subsequent code must process the result specially if
the input (42) is garbage is true of any language, whether or not null is
allowed. I still can't tell "by looking at it" what is happening.

In fact, I would reason differently about this code if the comments were
removed and the names changed:

    
    
        var a = new B();
        var c = d.E(42);
    

In this context, it seems the real error is that an invalid parameter value is
passed, so I'd see if I could fix that first, _possibly_ eliminating the need
for any error handling code. That approach might be common for a functional
mindset, but not exclusively so.

------
matthewmacleod
If you ignore the clickbait use of the word 'reasonable', then there are some
valid points made here. The question is – what's the benefit?

There are definite benefits to using a language that it's easy to reason
about. In most cases, there's also a cost. That's fine – it means we've got
the ability to trade off one against the other as the situation requires.

I'm unlikely to write tiny, single-use scripts in a strict, statically-typed
language – mostly because the overhead isn't worth it. Similarly, systems that
require higher levels of correctness can benefit from the guarantees that are
offered by stricter languages.

We have to bear in mind that the entire field of programming languages is
still very much evolving, as we gain experience of what works and what
doesn't. Type inference, for example, can drastically reduce the overhead of
type checking. Or option types, which eliminate a class of errors by providing
support for common patterns. No doubt as the field evolves, we'll see that
languages emerge which deal with the pain points of both 'reasonable' and
'unreasonable' languages.

~~~
klibertp
> We have to bear in mind that the entire field of programming languages is
> still very much evolving, as we gain experience of what works and what
> doesn't. Type inference, for example, can drastically reduce the overhead of
> type checking.

I'm sorry, it's just too much for me. Yes, PL theory advances and yes, there
are many new, interesting ideas being presented each year. That's true.

But your example, "type inference", dates back to the sixties. Similarly for
"option types". Using these as an example of "evolution of entire field of
programming languages" would suggest this evolution happens at a glacial pace.
Which is indeed true for the so-called mainstream languages, but "the entire
field" is much, much larger than those, moves far quicker and comes up with
much more interesting ideas every year.

~~~
matthewmacleod
Yes, it does. But you're totally ignoring the practical ramifications of this
– the fact that ideas that are only now making it into mainstream programming
languages is a strong indication that the entire endeavour is more complex
than you're admitting.

We don't just pull language features out of our collective arses and start
using them. Evolution _does_ happen at a glacial pace – we stick features into
minority-appeal languages; they kick around a bit; people rediscover these
features later, and maybe they eventually end up in popular languages. But
there's a huge amount more involved in that process than simply coming up with
the feature - testing, maintainability, long-term implications, unforeseen
complexity, programmer acceptance, performance constraints… the list goes on.

~~~
klibertp
> testing, maintainability, long-term implications, unforeseen complexity,
> programmer acceptance, performance constraints… the list goes on.

No, it's actually just "programmer acceptance" and secondary reasons like
amount of money poured into marketing or language being tied to an OS. I'm not
very pleased with this. In this talk:
[https://thestrangeloop.com/sessions/the-sociology-of-
program...](https://thestrangeloop.com/sessions/the-sociology-of-programming-
languages) it's said that probability of language being used is "potential
gains/pain of adoption" ratio. That's true. Language designers, at least the
ones who want their languages to succeed, constrain themselves to make it as
painless as possible for "normal programmers" to pick up. Nobody seems to
notice that there's another option of making denominator smaller: all you need
is to become better at adopting new technologies. But this somehow doesn't
work, because... Probably because of long-term implications or performance
constraints, right.

------
thoman23
Great article. Couldn't agree more. These are all reasons why I don't
understand why there is this rush to embrace Javascript on the server side,
the one place where you are actually free to use a "reasonable" language.

~~~
JoeAltmaier
Half the app runs on the server (maybe more). Its helpful to use a familiar
toolchain across the whole app.

~~~
mrec
Maybe. It's a high price to pay for that, though. And with the rise of JS-as-
target tools like asm.js and WebSharper, that toolchain doesn't necessarily
have to be Javascript.

------
marxama
> 6\. Nulls are NOT allowed, in general.

I really want to like F#, but that's a really big "in general". I love the
idea of option types, but I often hear with regards to F#, "forget about
NullReferenceExceptions!". Yeah, that's nice, except I sometimes use strings
in my code...

What I would've liked is to have F# strictly forbid nullable references, and
treat all reference types in interop situations as (implicitly) options. Not
sure if that would be possible, haven't given it too much thought and I'm sure
there are tons of tricky cases that haven't occurred to me, but I haven't
really seen this discussed anywhere.

------
josephlord
Swift passes the test in my view provided you can cope with using the word
struct instead of object. (Objects based on classes are reference types in
Swift but structs, enums and the default collections are value types).

You can write pretty functional code if you want but you also have the option
to write more mutable/side effecty/stateful object code if you want.

~~~
jdpage
So does Rust, I think. 2014 was a good year for programming languages.

~~~
klibertp
> 2014 was a good year for programming languages

Yeah... another batch of innovative, interesting languages died because "it's
not practical", another pile of language features didn't manage to get
implemented because "but look at syntax, it's ugly", another bunch of
languages took some decades old features, dumbed them down as much as possible
and then some more (because "it would be to hard to use otherwise") and
marketed them as ground-breaking improvements to the art of programming.

Very good year for PLs, indeed.

~~~
matthewmacleod
Have you got any concrete examples, or are you just going to complain?

The entire field of programming language design is more complex than you seem
to be admitting.

------
hawleyal
> How to make your language predictable: > 1\. Variables should not be allowed
> to change their type.

Completely disagree.

~~~
mannykannot
The author presented an argument for this proposition. Do you have an argument
against it?

~~~
hawleyal
Even JavaScript, which is much maligned for it's poor implementation of
dynamic typing, has clear rules for type coercion.

In the author's example in support of "Variables should not be allowed to
change their type," the variable "x" is subject to coercion, but the real
problem was poor scoping by using the global value instead of the parameter.

This would be the same scoping problem, even if the variable type was not
changed. Any non-deterministic function that modifies existing state can be
said to produce unexpected/unpredictable/unreasonable results. In this case,
the unpredictability was not due to a variable changing type.

