Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

A syntax question

8 views
Skip to first unread message

Ron Garret

unread,
Dec 21, 2006, 3:09:37 PM12/21/06
to
This is almost certainly a FAQ so if someone can just point me to the
appropriate place that would be much appreciated.

I come from a Lisp background, so the concepts of functional programming
come very naturally to me, but I'm having the very devil of a time
wrapping my brain around the syntax. My understanding is that:

f a b

means (using Scheme notation): (f a b) which is equivalent (thanks to
currying) to ((f a) b) UNLESS 'a' has been defined as an infix operator,
in which case "f a b" means (a f b) == ((a f) b).

Question 1: Is that right?

Question 2: When you're reading code and you see "a b c" how are you
supposed to know whether it means ((a b) c) or ((b a) c)?

Thanks,
rg

Message has been deleted

Ron Garret

unread,
Dec 21, 2006, 3:55:51 PM12/21/06
to
In article <notation-20...@ram.dialup.fu-berlin.de>,
r...@zedat.fu-berlin.de (Stefan Ram) wrote:

> Ron Garret <rNOS...@flownet.com> writes:
> >My understanding is that:
> >f a b
> >means (using Scheme notation): (f a b)
>

> To me, the notion of a meaning does not make sense unless the
> language to be used for interpretation is given. »Functional
> programming« is not a language.

My understanding was that there is a common syntactic convention used in
most modern functional languages (i.e. ML, Haskell, Miranda...). But if
there isn't, then let's constrain it to Haskell. That seems to be what
all the cool kids are using nowadays.

rg

Mark T.B. Carroll

unread,
Dec 21, 2006, 4:26:27 PM12/21/06
to
Ron Garret <rNOS...@flownet.com> writes:

> Question 1: Is that right?

Looks about right.

> Question 2: When you're reading code and you see "a b c" how are you
> supposed to know whether it means ((a b) c) or ((b a) c)?

With Haskell, it's what characters are used. Words drawn from [a-z] can
only become infix operators when you put them in backquotes. You'll see
all the Haskell infix operators are +, >>, etc. and things like `mod`
are used thusly as infix operators. mod is a function name that,
brushing precedence under the rug, works rather like a prefix operator,
and you can put parentheses around the infix ones to make them prefix,
e.g., (+) 1 2

HTH.

Mark.

--
Functional programming vacancy at http://www.aetion.com/

Greg Buchholz

unread,
Dec 21, 2006, 5:48:24 PM12/21/06
to
Ron Garret wrote:
> My understanding was that there is a common syntactic convention used in
> most modern functional languages (i.e. ML, Haskell, Miranda...). But if
> there isn't, then let's constrain it to Haskell. That seems to be what
> all the cool kids are using nowadays.

In Haskell, infix operators are made up of the following symbols
ASCII...

!#$%&*+./<=>?@\^|-~

...plus some Unicode characters. You can also make "ordinary"
identifiers into infix ones by enclosing them in backquotes. And you
can apply the infix operators normally, by enclosing them in
parenthesis. Some examples...

Prelude> let a >:-| b = a + b
Prelude> 4 >:-| 5
9
Prelude> let x /\/\/ y = x + y
Prelude> 4 /\/\/ 5
9
Prelude> (+) 4 5
9
Prelude> div 20 5
4
Prelude> 20 `div` 5
4
Prelude> (/ 4) 20
5.0
Prelude> (4 /) 20
0.2


...See also section 2 of the Haskell Report...
http://www.haskell.org/onlinereport/

Greg Buchholz

Ron Garret

unread,
Dec 21, 2006, 7:24:25 PM12/21/06
to
In article <1166741304.0...@f1g2000cwa.googlegroups.com>,
"Greg Buchholz" <sleeping...@yahoo.com> wrote:

Thanks!

rg

Dirk Thierbach

unread,
Dec 22, 2006, 6:20:14 AM12/22/06
to
Ron Garret <rNOS...@flownet.com> wrote:
> I come from a Lisp background, so the concepts of functional programming
> come very naturally to me, but I'm having the very devil of a time
> wrapping my brain around the syntax.

> Question 2: When you're reading code and you see "a b c" how are you

> supposed to know whether it means ((a b) c) or ((b a) c)?

Additionally to what has already been said, you should keep in mind
that all infix operators have priority and associativity. They are
declared by "infixr" (right associative), "infixl" (left associative),
"infix" (not associative).

The Prelude (i.e., the Haskell standard library) for example has the
following fixity declarations:

infixr 9 .
infixl 9 !!
infixr 8 ^, ^^, **
infixl 7 *, /, `quot`, `rem`, `div`, `mod`, :%, %
infixl 6 +, -
infixr 5 :
infixr 5 ++
infix 4 ==, /=, <, <=, >=, >, `elem`, `notElem`
infixr 3 &&
infixr 2 ||
infixl 1 >>, >>=
infixr 1 =<<
infixr 0 $, $!, `seq`

The means that "a + b * c" means the same as "(+) a ((*) b c)", as
one would expect. The operators (.) and ($) are composition and
application, i.e.

(f . g) x = f (g x))

f $ x = f x

and this allows some interesting idioms, for example "pipes" that
do processing in multiple steps (read from right to left):

doAll arg = doStep3 $ doStep2 $ doStep1 $ arg

or, with composition:

doAll = doStep3 . doStep2 . doStep1

One can also use infix operators as "syntactic sugar", to implement
a domain-specific sublanguage. There are for example some parser
libraries that make use of that idea, so one can write down grammar
rules in a form that reads a bit like a BNF. In Lisp, one would use
macros for that.

- Dirk


Jon Harrop

unread,
Dec 22, 2006, 9:16:46 AM12/22/06
to
Ron Garret wrote:
> My understanding was that there is a common syntactic convention used in
> most modern functional languages (i.e. ML, Haskell, Miranda...).

ML is a family of languages including Caml derivatives (Caml-light, OCaml,
F#, MetaOCaml, GCaml, JCaml, HashCaml, ...) and core-ML derivatives
(Standard ML, AliceML, Cambridge ML, Concurrent ML, ...).

OCaml is the most popular of all of those languages. I expect F# to become
the most popular over the next few years.

In OCaml, "f a b" means the curried function application "(f(a))(b)" and
there is no ambiguity.

If the "a" stands for an infix operator in OCaml then you know it is a
symbol or "word" composed of symbols. If the latter, it adopts the
precedence and associativity defined for the first symbol in the "word".
For example, a new operator @@:

# let ( @@ ) a b = Array.concat [a; b];;
val ( @@ ) : 'a array -> 'a array -> 'a array = <fun>

adopts the precedence and associativity (right) of the built-in "@" operator
(list append).

> But if
> there isn't, then let's constrain it to Haskell. That seems to be what
> all the cool kids are using nowadays.

Like ML, Haskell is a family of languages but Haskell is quite different:
pure and lazy with type classes.

--
Dr Jon D Harrop, Flying Frog Consultancy
Objective CAML for Scientists
http://www.ffconsultancy.com/products/ocaml_for_scientists/index.html?usenet

Dan Bensen

unread,
Dec 22, 2006, 9:17:58 PM12/22/06
to
Ron Garret wrote:
> My understanding is that:
> f a b
> means (using Scheme notation): (f a b) which is equivalent (thanks to
> currying) to ((f a) b) UNLESS 'a' has been defined as an infix operator,
> in which case "f a b" means (a f b) == ((a f) b).
> Question 1: Is that right?
Normally you would put an operator in parens to pass it as a function
arg, e.g.
sum = foldr (+) 0

> Question 2: When you're reading code and you see "a b c" how are you
> supposed to know whether it means ((a b) c) or ((b a) c)?

If b is a bare operator (not in parens),
a b c == (b) a c
e.g.
f . g == (.) f g

As Greg said, anything whose name is punctuation chars is an operator
rather than a function.

--
Dan
www.prairienet.org/~dsb

Ron Garret

unread,
Dec 23, 2006, 6:58:28 PM12/23/06
to
In article <2006122211201...@dthierbach.news.arcor.de>,
Dirk Thierbach <dthie...@usenet.arcornews.de> wrote:

Why not just:

doAll arg = doStep3 doStep2 doStep1 arg

or even:

doAll = doStep3 doStep2 doStep1

?

rg

Marcin 'Qrczak' Kowalczyk

unread,
Dec 23, 2006, 7:16:50 PM12/23/06
to
Ron Garret <rNOS...@flownet.com> writes:

>> doAll arg = doStep3 $ doStep2 $ doStep1 $ arg
>>
>> or, with composition:
>>
>> doAll = doStep3 . doStep2 . doStep1
>
> Why not just:
>
> doAll arg = doStep3 doStep2 doStep1 arg

Because this means ((doStep3 doStep2) doStep1) arg, which is a way
(the standard way in many functional languages) to express a function
with multiple arguments, which is more common than applying several
one-argument functions in sequence.

--
__("< Marcin Kowalczyk
\__/ qrc...@knm.org.pl
^^ http://qrnik.knm.org.pl/~qrczak/

Ron Garret

unread,
Dec 23, 2006, 7:40:48 PM12/23/06
to
In article <871wmqb...@qrnik.zagroda>,

Marcin 'Qrczak' Kowalczyk <qrc...@knm.org.pl> wrote:

> Ron Garret <rNOS...@flownet.com> writes:
>
> >> doAll arg = doStep3 $ doStep2 $ doStep1 $ arg
> >>
> >> or, with composition:
> >>
> >> doAll = doStep3 . doStep2 . doStep1
> >
> > Why not just:
> >
> > doAll arg = doStep3 doStep2 doStep1 arg
>
> Because this means ((doStep3 doStep2) doStep1) arg, which is a way
> (the standard way in many functional languages) to express a function
> with multiple arguments, which is more common than applying several
> one-argument functions in sequence.

Ah. So f $ g == (f g) == f g but f $ g $ h == (f (g h)) != f g h == ((f
g) h), right?

So what's the difference between f $ g $ h and f . g . h? (Are the
spaces required BTW? Can I write f$g$h and f.g.h?)

Is there a concise reference that explains all this?

rg

Marcin 'Qrczak' Kowalczyk

unread,
Dec 23, 2006, 8:32:27 PM12/23/06
to
Ron Garret <rNOS...@flownet.com> writes:

> Ah. So f $ g == (f g) == f g but f $ g $ h == (f (g h)) != f g h == ((f
> g) h), right?

Right.

> So what's the difference between f $ g $ h and f . g . h?

'f $ g $ h' and 'f . g $ h' are 'f (g h)', while 'f . g . h'
is '\x -> f (g (h x))'. And 'f $ g . h' is 'f (\x -> g (h x))'.

> (Are the spaces required BTW? Can I write f$g$h and f.g.h?)

Spaces are not required around operators. Almost.

The . symbol for function composition in Haskell was not the most
fortunate choice. 'Foo.bar' with a capitalized Foo means bar from
the module Foo, while 'Foo . bar' means Foo composed with bar
(when the . symbol was being chosen for function composition, Haskell
did not have the 'Foo.bar' syntax yet). Also, there have been some
experimental Haskell extensions where 'foo.bar' meant field bar of
record foo.

Haskell has only binary operators (except '-' for negation, and '~'
and '!' for certain rare constructs), which implies that the grammar
doesn't need two operators in a row, which means that a problem with
deciding where to split a sequence of operator-like characters doesn't
arise. Also, the characters ()[]{} can't appear in an operator name.
For these reasons, cases where a space is required before or after an
operator are very rare.

> Is there a concise reference that explains all this?

I don't remember a reference besides the Haskell 98 Report.

Dan Bensen

unread,
Dec 23, 2006, 9:16:17 PM12/23/06
to
Ron Garret wrote:
> Is there a concise reference that explains all this?
http://www.zvon.org/other/haskell/Outputglobal/index.html

--
Dan
www.prairienet.org/~dsb

Ron Garret

unread,
Dec 24, 2006, 1:59:02 AM12/24/06
to
In article <87hcvm8...@qrnik.zagroda>,

Marcin 'Qrczak' Kowalczyk <qrc...@knm.org.pl> wrote:

> Ron Garret <rNOS...@flownet.com> writes:
>
> > Ah. So f $ g == (f g) == f g but f $ g $ h == (f (g h)) != f g h == ((f
> > g) h), right?
>
> Right.
>
> > So what's the difference between f $ g $ h and f . g . h?
>
> 'f $ g $ h' and 'f . g $ h' are 'f (g h)', while 'f . g . h'
> is '\x -> f (g (h x))'. And 'f $ g . h' is 'f (\x -> g (h x))'.

Oh my. Now I understand why Haskell is so popular in academia. Tidbits
like that must make it easy to generate questions for the exam ;-)

One last question: how does juxtaposition fit into the scheme of things?
It's obviously left-associative but what is its precedence? And is that
defined in the prelude or just built in to the language?

rg

Marcin 'Qrczak' Kowalczyk

unread,
Dec 24, 2006, 5:13:47 AM12/24/06
to
Ron Garret <rNOS...@flownet.com> writes:

> One last question: how does juxtaposition fit into the scheme of things?
> It's obviously left-associative but what is its precedence?

Higher than operator application.

> And is that defined in the prelude or just built in to the language?

Built in.

Ron Garret

unread,
Dec 24, 2006, 12:29:34 PM12/24/06
to
In article <87zm9dy...@qrnik.zagroda>,

Marcin 'Qrczak' Kowalczyk <qrc...@knm.org.pl> wrote:

> Ron Garret <rNOS...@flownet.com> writes:
>
> > One last question: how does juxtaposition fit into the scheme of things?
> > It's obviously left-associative but what is its precedence?
>
> Higher than operator application.
>
> > And is that defined in the prelude or just built in to the language?
>
> Built in.

Thanks!

rg

0 new messages