![](/i/fill.gif) |
![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
On 10/05/2013 11:12 AM, scott wrote:
>>> Then perhaps it's a bad idea to create a programming language where
>>> using one vs. multiple whitespace at some point makes a syntactic or
>>> semantic difference.
>>
>> Perhaps. Most people seem OK once you explain that it's the whitespace
>> that's causing their problem. Generally these same people don't make
>> that particular mistake again.
>
> Doesn't it prevent you adding in extra whitespace for readability? That
> seems like quite a limitation.
Not really.
It's not like the rule says "you must have exactly X characters of
whitespace here, and Y characters of whitespace there".
It's only line ends and indentation that carry any special significance.
The whitespace within the length of the line can work any way you fancy.
And the rule about indentation is just that nested scopes must be
indented further than the outer scope. the rule doesn't say by how much;
that's up to you.
It's not like, say, Makefiles, where you MUST use tab characters or it
doesn't work right. (I always thought that was absurdly stupid...)
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
On 09/05/2013 09:43 PM, andrel wrote:
> obliatory reference:
> http://en.wikipedia.org/wiki/Whitespace_(programming_language)
"The idea of using whitespace characters as operators for the C++
language was facetiously suggested five years earlier by Bjarne Stroustrup."
Well, in a way, whitespace *is* an operator in Haskell. Or rather,
function application is an operator (it even has an operator
precedence), and function application is denoted by whitespace in Haskell.
In other way, inside a do-block, every end of line is replaced by the
">>" or ">>=" operator. So end of line is a bit like an operator.
(Although you can write explicit ";" characters if you prefer.)
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Am 09.05.2013 21:54, schrieb Orchid Win7 v1:
> * Using tab characters instead of spaces.
>
> Whitespace is used to delimit scope in Haskell. A space character is 1
> space wide; a tab character is a different randomly-chosen size in every
> program known to Man. That means that text which appears to line up in
> your text editor may look completely wrong in a different program - or
> to the Haskell compiler, for that matter.
... which is why placing importance on indentation in a programming
language constitutes a design flaw...
> * Calling functions with tuples.
>
> In anything derived from ALGOL, a function call looks like
>
> foo(1, 2, 3)
>
> But in Haskell, the correct syntax is
>
> foo 1 2 3
>
> This works exactly like Bash scripts; the first "word" is the function
> to call, and all subsequent words are arguments. This becomes slightly
> confusing because you can pass a function as an argument to another
> function. That means that the first word is the function to call, but
> the other words might ALSO be functions. Regardless, the FIRST word is
> always the function being called.
I think this is actually a pretty stupid notation for a functional
programming language; after all, the braced notation is /the/
traditional notation for functions in mathematics.
I'd go even further and question the whole concept of passing multiple
arguments to a function. You can't output multiple values from a
function (unless using a tuple), so why should you input multiple values
(unless using a tuple)?
> Code: print -2
> Means: print - 2 (I.e., subtract 2 from print.)
> Intended: print (-2) (I.e., print out -2.)
>
> Notice how all three of these are the exact same bug; function
> application has the highest precedence of any operator, which apparently
> isn't what people are expecting. (The final example is arguably a bug in
> the language specification, but there you have it.)
I wouldn't call the latter case a bug in the language spec. It's the
whole idea of making function application have highest precedence that
I'd call a bug.
BTW this wouldn't be a problem if Haskell used the classic "fn(x,y,z)"
notation for functions.
> Lots of people try to write Haskell like
>
> data Foobar = Foobar {foo :: Int, bar :: Int, baz :: Int}
> data Fizz = Fizz {foo :: Bool, wok :: Int}
>
> This doesn't work at all, due to a namespace collision. Basically when
> you define a named field, it also auto-generates a function to fetch the
> value of that field. That is,
>
> foo :: Foobar -> Int
> bar :: Foobar -> Int
> ...etc...
>
> Naturally, there can only be one function in scope named "foo". The net
> upshot of this is that no two records may ever have fields with the same
> name. This is widely considered a language design bug, but nobody has
> yet come up with a satisfactory solution to the problem.
A /severe/ design bug, if I'm asked. Nothing I'd expect from a
contemporary programming language.
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
clipka <ano### [at] anonymous org> wrote:
> I'd go even further and question the whole concept of passing multiple
> arguments to a function. You can't output multiple values from a
> function (unless using a tuple), so why should you input multiple values
> (unless using a tuple)?
There's basically no difference between binary operators and functions
in mathematics. A binary operator is, basically, a function taking two
values and returning one.
I don't think it's in any way incorrect in mathematics to use a function
notation for binary (or ternary, etc.) operations.
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
>> Whitespace is used to delimit scope in Haskell. A space character is 1
>> space wide; a tab character is a different randomly-chosen size in every
>> program known to Man.
>
> ... which is why placing importance on indentation in a programming
> language constitutes a design flaw...
Well, you can say that if you wish. I'm not going to agree with you
though. :-P
It's really quite irritating to have your program not compile just
because you accidentally left out a semicolon with it's damned obvious
what you actually meant. Haskell means I never have to worry about this.
>> * Calling functions with tuples.
>>
>> In anything derived from ALGOL, a function call looks like
>>
>> foo(1, 2, 3)
>>
>> But in Haskell, the correct syntax is
>>
>> foo 1 2 3
>
> I think this is actually a pretty stupid notation for a functional
> programming language; after all, the braced notation is /the/
> traditional notation for functions in mathematics.
No, no it is not.
Consider, for example, Euler's relation. It is customarily written as
exp ix = cos x + i sin x
It is NOT typically written as
exp(ix) = cos(x) + i sin(x)
except when written in computer source code.
> I'd go even further and question the whole concept of passing multiple
> arguments to a function. You can't output multiple values from a
> function (unless using a tuple), so why should you input multiple values
> (unless using a tuple)?
That is a whole other question, of course.
There are plenty of standard mathematical functions which take multiple
arguments. (GCD, anyone?) When it comes to computers, there is a simple
and easy way of implementing passing multiple bits of data to a
subroutine at once; if anything, the strange thing is that nobody has
come up with a programming language that lets you RETURN several items
at once. At the machine level, this would be a very easy thing to
implement. I can only imagine it's because nobody has come up with a
nice notation for writing it...
>> Code: print -2
>> Means: print - 2 (I.e., subtract 2 from print.)
>> Intended: print (-2) (I.e., print out -2.)
>>
>> Notice how all three of these are the exact same bug; function
>> application has the highest precedence of any operator, which apparently
>> isn't what people are expecting. (The final example is arguably a bug in
>> the language specification, but there you have it.)
>
> I wouldn't call the latter case a bug in the language spec. It's the
> whole idea of making function application have highest precedence that
> I'd call a bug.
Consider, for example, the expression
tan x = cos x / sin x
Here operator precedence does EXACTLY what we want it to do. Consider
another example:
string = printf "%x" value1 ++ show value2 ++ unlines list3
Here, again, we concatenate the output from several different functions
into a single string, and operator precedence works exactly how we want
it to, without needing any brackets.
I suspect that basically for any possible choice of precedences, you
will nearly always be able to find an example where it doesn't work how
you'd like it to. Never the less, I think the current operator
precedences work pretty well.
> BTW this wouldn't be a problem if Haskell used the classic "fn(x,y,z)"
> notation for functions.
That's true. But then again, remember that Haskell allows you to call a
function with a different number of arguments than the function expects.
That's probably the main reason why it doesn't use that syntax.
>> Lots of people try to write Haskell like
>>
>> data Foobar = Foobar {foo :: Int, bar :: Int, baz :: Int}
>> data Fizz = Fizz {foo :: Bool, wok :: Int}
>>
>> This doesn't work at all, due to a namespace collision.
>
> A /severe/ design bug, if I'm asked. Nothing I'd expect from a
> contemporary programming language.
It's embarrassing, sure. But it's not really an especially severe bug;
it's just a nuisance having to manually prefix all your field names with
the name of the type that they belong to (or some abbreviation thereof).
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Am 11.05.2013 23:21, schrieb Orchid Win7 v1:
>>> Lots of people try to write Haskell like
>>>
>>> data Foobar = Foobar {foo :: Int, bar :: Int, baz :: Int}
>>> data Fizz = Fizz {foo :: Bool, wok :: Int}
>>>
>>> This doesn't work at all, due to a namespace collision.
>>
>> A /severe/ design bug, if I'm asked. Nothing I'd expect from a
>> contemporary programming language.
>
> It's embarrassing, sure. But it's not really an especially severe bug;
> it's just a nuisance having to manually prefix all your field names with
> the name of the type that they belong to (or some abbreviation thereof).
... which is exactly why namespaces were invented in the first place.
Any contemporary programming language that bothers to use namespaces
should avoid such nuisances once and for all.
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
>>>> This doesn't work at all, due to a namespace collision.
>>>
>>> A /severe/ design bug, if I'm asked. Nothing I'd expect from a
>>> contemporary programming language.
>>
>> It's embarrassing, sure. But it's not really an especially severe bug;
>> it's just a nuisance having to manually prefix all your field names with
>> the name of the type that they belong to (or some abbreviation thereof).
>
> ... which is exactly why namespaces were invented in the first place.
> Any contemporary programming language that bothers to use namespaces
> should avoid such nuisances once and for all.
Well, the other alternative is to define each record in a separate
compilation unit. That'll do it. But that's also rather inconvenient.
In mitigation, Haskell programs tend not to have quite so many data type
definitions as a typical C program, and they tend to have a lot fewer
fields. That's not to say that name collisions don't happen though.
There have been a couple of solutions suggested. GHC has a mode in which
names are allowed to overlap, and the compiler tries to "guess" what you
meant at compile-time. This mostly works, but many people consider it to
be a deeply evil hack. Then there's Frege, which is basically a very
slightly modified Haskell which compiles to Java source code. In Frege,
every type is its own namespace, and in case of ambiguity you must
prefix the field name with the type name. (Note that C# does this with
enum values.)
Ultimately the problem is type inference. Pascal lets you write
"foo.bar" to access a field - but then, in Pascal the type of "foo" must
be explicitly stated in a type signature. Haskell is trying to let you
write the same expression but still let the compiler automatically
detect the type of "foo" - a much harder problem...
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
> It is NOT typically written as
>
> exp(ix) = cos(x) + i sin(x)
>
> except when written in computer source code.
Isn't that just because in maths the brackets are usually left out with
standard functions if it's obvious what the parameter is? For more
complex parameters brackets are usually used to avoid any ambiguity.
When writing "user defined" functions like f(x) in maths you always use
brackets.
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
On 13/05/2013 08:20 AM, scott wrote:
>> It is NOT typically written as
>>
>> exp(ix) = cos(x) + i sin(x)
>>
>> except when written in computer source code.
>
> Isn't that just because in maths the brackets are usually left out with
> standard functions if it's obvious what the parameter is? For more
> complex parameters brackets are usually used to avoid any ambiguity.
You leave out the brackets unless there's grounds for confusion. Which
is pretty much what Haskell does. (And what most other programming
languages do for everything except subroutine arguments.)
> When writing "user defined" functions like f(x) in maths you always use
> brackets.
Pro tip: Don't use the word "always" around mathematicians. It tends to
make them find obscure counter-examples. ;-)
(Why, I have a book somewhere which claims that a "function" is actually
a set of 2-tuples...)
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
> You leave out the brackets unless there's grounds for confusion. Which
> is pretty much what Haskell does.
A mathematician would not expect any confusion with an expression like
sin 2x, so would leave out the brackets.
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |