Enhanced type guard syntax]

Joe Armstrong <>
Thu Sep 18 15:51:50 CEST 2003


> % The type constraint expressed directly in the argument list
> % Shorter to write
> % Exactly the same semantics as the foo example above
> % The compiler has potential of handling these type constraints more
> efficiently than today
> % and this syntax makes the different type of guards more visible
> %
> foo(A/integer, B/integer) ->
>       A * B.
> 
> 
> {X/float, Y/float} = graph:coordinates(),
> 
> The rationale behind this suggestion is that we already have the
> Variable/type syntax in the matchexpressions for binaries (example:
> <<Size,B:Size/binary,Rest/binary>> = <<2,"AB","CD">>)
> It is unfair that some types can be matched without guard syntax while
> others can't.
> It will result in a more compact and intuitive way of writing that will
> encourage writing type constraints which will catch errors as early and
> efficient as possible. The allowed type specifiers should be all the
> type test BIFs named is_XXX/1 but without the "is_" prefix.
> 


  Adding  guards  like  this   violates  one  of  my  favorite  design
meta-principles:

  " If  you add something  to a language  you have to  chuck something
away "

  What are we going to chuck away?

  Well not "when ->" ...

  Since you can't say

	foo(X, Y) when X == 2*Y ->

  in the new syntax

  So you keep "when" - now there are TWO ways of saying things

	foo(A/integer, B/integer)

  or

	foo(A, B) when is_integer(A), is_integer(B) ->

  and people will write:

	foo(A/integer, B) when is_integer(B) ->
	    ...

  etc.

  And the integer guard test is proposed to be called integer in one place
and is_integer somewhere else

  Adding the new syntax without removing something will *increase* the
complexity of the language. Since the change adds no semantic power
I am against it.

  Now if you want to add something add "proper" structs and throw away
records and include files with record headers.

  Meta comment - Erlang is becoming more and more complicated.

  Can we please start checking stuff away to make the language simple.

  To hasten this process I'd like to add a new declaration to the
the language.

  All modules should start.

	  -needsErlangVersion(N).

  	  Where N is the language version.

  Then  when  you add/remove  language  features  you  will know  what
version of the  compiler handles what feature. There  is nothing worse
than writing  some code using the  "latest" version of  the system and
posting the code  to somebody using an earlier version  just to be told
that "the program doesn't work".

  Suppose:
	
	1) I write a program using  version (say) 5 of the system,
           which has some feature not present in system version 4.
	2) I post the program to the net 
	3) Somebody running version 4 tries running my program

  When they do 3 they should get a *helpful* message -

	 You need version 5 of the system -
	 do you want me to live-update your system:  [y]

  They type y - and the system gets the latest version of the system
and installs it for them :-)

  What I do not want to happen if for either the compilation of execution
to fail and for them to send me a bug report - this has happened *many* times.

  Then once we have got the versioning in we can start chucking things
away.

  Get rid of spawn(Mod,Func,Args) ... and all the stupid
"having to export spawned functions" these are hangbacks to the days before
funs.  You only need spawn(fun() -> ...)

  Keeping  the  system   backwards  compatible  builds  up  *enormous*
problems in the future - by all means add things - but throw away the old
junk at the same time.

  If you number the versions with needsErlangVersion(N) you will even be
able to semi-automate the transition from one version to another.

  Without knowing the language version this is difficult

  /Cheers

  Joe





More information about the erlang-questions mailing list