POV-Ray : Newsgroups : povray.off-topic : I'm in the mood for monads Server Time
29 Oct 2026 18:51:40 EDT (-0400)
  I'm in the mood for monads (Message 44 to 93 of 93)  
<<< Previous 43 Messages Goto Initial 50 Messages
From: Darren New
Subject: Re: I'm in the mood for monads
Date: 22 Apr 2012 23:47:18
Message: <4f94d0c6@news.povray.org>
On 4/22/2012 11:34, Orchid Win7 v1 wrote:
> Oh, so it can capture local variables too? That's even better than I thought...

It can capture values of local variables, or references to non-local (to the 
lambda) variables. It doesn't really capture variables.

-- 
Darren New, San Diego CA, USA (PST)
   "Oh no! We're out of code juice!"
   "Don't panic. There's beans and filters
    in the cabinet."


Post a reply to this message

From: Darren New
Subject: Re: Living in a box
Date: 22 Apr 2012 23:51:26
Message: <4f94d1be@news.povray.org>
On 4/21/2012 14:37, Orchid Win7 v1 wrote:
> Again, this obviously doesn't actually work in C++, but it makes the example
> code much easier to write.

Note that both of these are perfectly fine in C#. :-)

> Incidentally, since C++ REALLY DOES have a function type (or at least,
> function POINTER type) which can be passed as an argument, it's one of the
> few languages where it ought to be possible to implement a monad "for real".
> I might try it if I get the time.

There are lots of languages that let you can pass a function as an argument.

-- 
Darren New, San Diego CA, USA (PST)
   "Oh no! We're out of code juice!"
   "Don't panic. There's beans and filters
    in the cabinet."


Post a reply to this message

From: Invisible
Subject: Re: Living in a box
Date: 23 Apr 2012 04:04:48
Message: <4f950d20$1@news.povray.org>
On 23/04/2012 04:51 AM, Darren New wrote:
> On 4/21/2012 14:37, Orchid Win7 v1 wrote:
>> Again, this obviously doesn't actually work in C++, but it makes the
>> example code much easier to write.
>
> Note that both of these are perfectly fine in C#. :-)

I'd be surprised if I just happened to guess the right syntax for it. ;-)

>> Incidentally, since C++ REALLY DOES have a function type (or at least,
>> function POINTER type) which can be passed as an argument, it's one of
>> the
>> few languages where it ought to be possible to implement a monad "for
>> real".
>
> There are lots of languages that let you can pass a function as an
> argument.

Heh. I bet most of them are scripting languages though. :-P


Post a reply to this message

From: Invisible
Subject: Re: I'm in the mood for monads
Date: 23 Apr 2012 04:07:02
Message: <4f950da6@news.povray.org>
On 22/04/2012 07:19 PM, Warp wrote:
> http://byorgey.files.wordpress.com/2011/05/monad_tutorial.jpg

Coming back to what I said earlier... Monads aren't actually that 
complicated. It's just that it's a rather abstract idea, and it's not 
really "like" anything else most programmers will be familiar with.

I think the huge profusion of monad tutorials just reinforces the idea that

1. Monads are really, really hard.

2. Monads are incredibly important. (I.e., if you don't understand them, 
you can never use Haskell.)

3. Once you understand them, it will fundamentally change your life.

None of these statements are actually true...


Post a reply to this message

From: clipka
Subject: Re: Living in a box
Date: 23 Apr 2012 05:33:42
Message: <4f9521f6$1@news.povray.org>
Am 23.04.2012 10:05, schrieb Invisible:

>>> Incidentally, since C++ REALLY DOES have a function type (or at least,
>>> function POINTER type) which can be passed as an argument, it's one of
>>> the
>>> few languages where it ought to be possible to implement a monad "for
>>> real".
>>
>> There are lots of languages that let you can pass a function as an
>> argument.
>
> Heh. I bet most of them are scripting languages though. :-P

Meh. Even good old Turbo Pascal had function pointers.


Post a reply to this message

From: Invisible
Subject: Re: Living in a box
Date: 23 Apr 2012 05:37:38
Message: <4f9522e2$1@news.povray.org>
>>> There are lots of languages that let you can pass a function as an
>>> argument.
>>
>> Heh. I bet most of them are scripting languages though. :-P
>
> Meh. Even good old Turbo Pascal had function pointers.

O RLY?

Because, I was actually *looking* for that feature, and couldn't find 
it. It would have been quite helpful...


Post a reply to this message

From: Invisible
Subject: High theory
Date: 23 Apr 2012 06:20:00
Message: <4f952cd0@news.povray.org>
OK, so "magma" consists of a set S and a binary operator #. The # 
operator takes any two elements of S (including the possibility of two 
copies of the same element), and yields a new element of S (possibly the 
same one you started with).

   ∀ x, y ∈ S, x # y ∈ S.

The only "rules" as such are picky, hair-splitting ones. Stuff like "x # 
y" must have a single, definite value for all possible inputs. (If, for 
example, # stands for division, then if y=0, there is no defined result. 
If we're working with integers only, 2/3 isn't an integer. And so on.)

A magma isn't especially interesting by itself. However, if we add the 
rule that # must be /associative/, then we got a "semigroup".

   ∀ x, y, z ∈ S, (x # y) # z = x # (y # z).

Already this begins to have interesting mathematical properties. But if 
we add a special /identity element/, we get a "monoid".

   ∃ i ∈ S: ∀ x ∈ S, i # x = x # i = x.

So what are we really saying? We're saying that a monoid is a set of 
things that have a procedure for combining them, and that there has to 
be a special one where combining it does nothing.

There are many possible examples of this. For example, if S is a set of 
numbers and # denotes addition, then 0 is our identity element. (Every 
child knows that x + 0 = x.) Less obviously, if # denotes 
multiplication, our identity element is 1. (Since 1 * x = x.)

But there are other examples too. If S is the set of all possible text 
strings, and # denotes concatenation, then the identity element is the 
empty string. (Appending or prepending an empty string does nothing.) If 
S is the set of all 1-argument functions [with the same return type as 
their argument type], and # denotes function composition, then the 
identity FUNCTION is the identity ELEMENT. (Bet you can't work out how 
/that/ naming scheme came about. :-P )

If you now take your monoid and give every element a corresponding 
/inverse element/, then you have a "group".

   ∀ x ∈ S, ∃ y ∈ S: x # y = y # x = i.

For example, in the monoid of numbers where # is addition, the inverse 
of (say) 5 would be -5. And hence, numbers and addition actually form a 
/group/, not just a monoid.

Considering strings, however, there is no string that you can append to 
something which "undoes" the act of appending an earlier string. So 
strings with concatenation form a monoid, but not a group.



All of this is fascinating, of course, but not directly related to MONADS.

If somebody asks "what is a monad?", the stereotypical response is

   "A monad is just a monoid in the category of endofunctors - what's 
the problem?"

The problem, obviously, is that if you don't know category theory, this 
makes not one shred of sense.

A less abstract way to think about it is this: If you have a value like 
x, you can put that inside a "box", which I will denote as [x]. Any 
value can be put in a box; in particular, you can put a /box/ in a box, 
for example [[x]].

Every /monad/ is also a /functor/. This merely means that there's a 
function (usually called "map"):

   map :: (x -> y) -> ([x] -> [y])

In other words, it takes a function that works an x-values, and turns it 
into a function that works on boxes containing x-values. (And instead of 
returning y-values, it now returns boxes containing y-values.) In 
summary, it "lifts" a function from working on values, to working on 
values in boxes.

The alternative way to think about map is

   map :: (x -> y) -> [x] -> [y]

In other words, given a function from x to y, and an x in a box, I will 
give you a y in a box.

Either way, there's a way to apply an ordinary function to values in 
boxes. Given that, there are two equivalent ways to define a monad. They 
both involve a function called "return":

   return :: x -> [x]

Return just takes a value and puts it in a box. "Inject" or "insert" 
might be a better name, but for some reason we're stuck with "return". 
Ho hum.

The other function is either "join" or "bind". One can be defined from 
the other - although this is highly non-obvious.

Join is the easy one to understand:

   join :: [[x]] -> [x]

It takes a box within a box, and gives you just a box. It removes one 
level of boxiness. That's pretty easy to comprehend.

Bind, on the other hand, has the hoopy type signature

   bind :: [x] -> (x -> [y]) -> [y]

In other words, given...
- An x in a box.
- A function that wants an x and gives you a y in a box
...I can give you a y in a box.

Notice how the x arrives IN A BOX, but the function expects a value NOT 
IN A BOX. So bind has to take a value /out/ of a box. Right? Right??

Actually... no. You can implement it just using join:

   bind box_x function = join (map function box_x)

Applying the function to the x inside the [x] yields a result of type 
[[y]]. Applying join to that turns it from [[y]] into [y] - the required 
result type.

Less obvious still is that join can be defined using bind:

   join bbx = bind bbx id

Here "id" is the identity function - i.e., a function that takes one 
argument, and just returns it unchanged. Recall that bind takes a value 
out of a box and passes it to a function. Well in this case, the value 
in the box is another box, so if we just /return/ that, we'll have only 
one level of boxing.

Usually it's bind that you actually want to /use/, and hence it's more 
efficient to define join in terms of bind, rather than the other way 
around. (Haskell actually lets you define return and bind without 
bothering with map at all. Map can be defined in terms of bind and 
return, after all: map f = bind (return . f).)



The really hoopy thing, of course, is that this "box" I keep talking 
about usually isn't just a simple box. (If it were, that would give you 
the identity monad, which is the most boring monad there is.) Usually 
it's something more interesting.

For example, if [x] represents a /list/ of x-values (as it does in 
Haskell, by the way), then [[x]] is a list of lists, and join is just 
flattening a list of lists into a single list. Alternatively, bind is 
mapping your function over every element of the list, and then 
flattening the resulting list of lists into a single list. (You will 
sometimes hear Haskell's bind operator is being "concatMap". "concat" is 
a standard library function that does what join does above; "concatMap" 
does the same as calling map and then concat.)

Sometimes, however, Haskellers do crazy things, like where your "box 
with an x in it" is actually a /function/ which takes half a dozen 
arguments and then /returns/ an x. For example, if [x] means "a function 
that takes a dictionary and then returns an x", then... Well, we end up 
with /a lot/ of different functions flying around, which can sound a bit 
confusing. But here it is:

- return(x) just generates a new function that accepts a dictionary, 
ignores it, and always returns x anyway.

- map(f,g) is easy enough. Return a function that takes a dictionary, 
calls g with that dictionary, and then applies f to the result.

- join(f) is taking a function that returns a function that returns an 
x. At this point we don't /have/ a dictionary, so we have nothing to 
actually /call/ f with as an argument. But we want to make a function 
that takes a dictionary and returns an x. So we write a function that 
takes a dictionary argument, calls f with it, and then calls the result 
of f again with the same argument.

- Given that we have join() and map(), it's clear that bind() should be 
implementable. But can we do it more directly? In fact, all bind(f,g) 
does is return a function that takes a dictionary, calls f with that 
argument, and then passes the result to g. Quite easy, really.

As a result of all this jiggery-pokery, you can write simple-looking 
code, but it invisibly has access to this dictionary that we keep 
passing around the place. For that to actually be useful, you need a way 
to /fetch/ the dictionary. You go that by writing a function like

   get_dictionary :: [dictionary]

Notice that this doesn't appear to be a /function/ at all; it takes no 
arguments, after all. But it appears to be a "dictionary in a box" - and 
as we just discussed, in this instance our "box" is really "a function 
that takes a dictionary and returns something". It should be obvious how 
you would write "a function that takes a dictionary and returns a 
dictionary".

So this complex arrangement of stuff allows every piece of code that 
runs inside this specific monad to have [read-only] access to a 
dictionary object. (Obviously it's not hard to change it to be some 
other sort of object instead.) This is the so-called "reader monad".

It's all fascinating stuff... but rather mind-bending in places. ;-)


Post a reply to this message

From: Invisible
Subject: Re: High theory
Date: 23 Apr 2012 06:25:23
Message: <4f952e13@news.povray.org>
> ∃ i ∈ S: ∀ x ∈ S, i # x = x # i = x.
> ∀ x ∈ S, ∃ y ∈ S: x # y = y # x = i.

Not that I wish to imply, in any way, that I'm bored or that my 
intellectual capabilities are not being fully utilised by my day job OR 
ANYTHING LIKE THAT... >_>


Post a reply to this message

From: clipka
Subject: Re: Living in a box
Date: 23 Apr 2012 09:38:53
Message: <4f955b6d$1@news.povray.org>
Am 23.04.2012 11:37, schrieb Invisible:
>>>> There are lots of languages that let you can pass a function as an
>>>> argument.
>>>
>>> Heh. I bet most of them are scripting languages though. :-P
>>
>> Meh. Even good old Turbo Pascal had function pointers.
>
> O RLY?
>
> Because, I was actually *looking* for that feature, and couldn't find
> it. It would have been quite helpful...

Might depend on the version; I know it was there in 6.0, because that's 
the one I used when I invented polymorphism (without the use of the OOP 
language extensions; I didn't have the faintest idea what OOP was all 
about, let alone that I was already using one of its core concepts).


Post a reply to this message

From: clipka
Subject: Re: High theory
Date: 23 Apr 2012 09:41:27
Message: <4f955c07$1@news.povray.org>
Am 23.04.2012 12:19, schrieb Invisible:
> OK, so "magma" consists of a set S and a binary operator #. The #
> operator takes any two elements of S (including the possibility of two
> copies of the same element), and yields a new element of S (possibly the
> same one you started with).

And here I was thinking that magma consisted of molten minerals...


Post a reply to this message

From: Invisible
Subject: Re: Living in a box
Date: 23 Apr 2012 09:43:34
Message: <4f955c86$1@news.povray.org>
>>> Meh. Even good old Turbo Pascal had function pointers.
>>
>> O RLY?
>>
>> Because, I was actually *looking* for that feature, and couldn't find
>> it. It would have been quite helpful...
>
> Might depend on the version; I know it was there in 6.0,

I only used 5.5

> because that's
> the one I used when I invented polymorphism (without the use of the OOP
> language extensions; I didn't have the faintest idea what OOP was all
> about, let alone that I was already using one of its core concepts).

Yeah, that's what I was trying to do too. ;-)

I love how 5.5 added "OOP", which consisted of letting you use the 
keyword "class" instead of "record", and letting you write your function 
code inside a class instead of outside it. I spent ages trying to figure 
out what advantage that gives you. And of course... IT DOESN'T. It's no 
different. In particular, IT'S NOT OOP.

It would have /actually/ been OO if it had let you make fields private, 
or if it supported dynamic binding. But noooo... :-P


Post a reply to this message

From: Invisible
Subject: Re: High theory
Date: 23 Apr 2012 09:44:06
Message: <4f955ca6$1@news.povray.org>
On 23/04/2012 02:41 PM, clipka wrote:
> Am 23.04.2012 12:19, schrieb Invisible:
>> OK, so "magma" consists of a set S and a binary operator #. The #
>> operator takes any two elements of S (including the possibility of two
>> copies of the same element), and yields a new element of S (possibly the
>> same one you started with).
>
> And here I was thinking that magma consisted of molten minerals...

For extra credit, work out the difference between a semigroup and a 
groupoid. :-P


Post a reply to this message

From: clipka
Subject: Re: High theory
Date: 23 Apr 2012 09:50:34
Message: <4f955e2a@news.povray.org>
Am 23.04.2012 12:19, schrieb Invisible:

> A less abstract way to think about it is this: If you have a value like
> x, you can put that inside a "box", which I will denote as [x]. Any
> value can be put in a box; in particular, you can put a /box/ in a box,
> for example [[x]].

I suggest thinking outside the box... (sorry, pun definitely intended).

Call it a wrapper object, and I guess we're fine.


Post a reply to this message

From: Invisible
Subject: Re: High theory
Date: 23 Apr 2012 09:55:50
Message: <4f955f66$1@news.povray.org>
On 23/04/2012 02:50 PM, clipka wrote:
> Am 23.04.2012 12:19, schrieb Invisible:
>
>> A less abstract way to think about it is this: If you have a value like
>> x, you can put that inside a "box", which I will denote as [x]. Any
>> value can be put in a box; in particular, you can put a /box/ in a box,
>> for example [[x]].
>
> I suggest thinking outside the box... (sorry, pun definitely intended).
>
> Call it a wrapper object, and I guess we're fine.

Well, "box" is fewer letters to type. ;-)

You can take the guy out of the Haskell, but you cannot take the Haskell 
out of the guy. o_O


Post a reply to this message

From: clipka
Subject: Re: Living in a box
Date: 23 Apr 2012 10:06:44
Message: <4f9561f4$1@news.povray.org>
Am 23.04.2012 15:43, schrieb Invisible:

> I love how 5.5 added "OOP", which consisted of letting you use the
> keyword "class" instead of "record", and letting you write your function
> code inside a class instead of outside it. I spent ages trying to figure
> out what advantage that gives you. And of course... IT DOESN'T. It's no
> different. In particular, IT'S NOT OOP.
>
> It would have /actually/ been OO if it had let you make fields private,
> or if it supported dynamic binding. But noooo... :-P

There is no language that "is OOP". OOP is a software design approach; 
An OO language (or OO language feature) is one that helps you implement 
such a design, but nothing more.

Bundling record data and related functions (aka methods) in a single 
thing called "class" does help you write software that makes use of data 
encapsulation (an OOP concept); it doesn't help you with enforcing the 
rules of encapsulation, but it simplifies the syntax by (1) 
automatically passing the ubiquitous "this" pointer, and (2) adding new 
namespaces to avoid naming collisions. As such, it does qualify as an OO 
language feature.

BTW, I'm not sure whether they added any new syntax features to classes 
from 5.5 to 6.0, but AFAIR 6.0 *did* support polymorphism; I think the 
"Turbo Vision" framework made excessive use of it.


Post a reply to this message

From: Invisible
Subject: Re: Living in a box
Date: 23 Apr 2012 10:14:06
Message: <4f9563ae$1@news.povray.org>
>> It would have /actually/ been OO if it had let you make fields private,
>> or if it supported dynamic binding. But noooo... :-P
>
> There is no language that "is OOP". OOP is a software design approach;
> An OO language (or OO language feature) is one that helps you implement
> such a design, but nothing more.

It came out around the time OOP was the latest crazy, and everything 
that wasn't OO was old and obsolete, and OO was the wave of the future. 
So they took the existing language, bolted on a few very superficially 
OO syntax elements, and said "Hey! Look! Our product is OO now! BUY IT!!"

About the only /useful/ thing it actually added was a per-type namespace 
for methods. What's it, really. You could /already/ group code and data 
together using modules, so the mere syntactic ability to write one 
inside the other isn't much of a big deal.

> BTW, I'm not sure whether they added any new syntax features to classes
> from 5.5 to 6.0, but AFAIR 6.0 *did* support polymorphism; I think the
> "Turbo Vision" framework made excessive use of it.

I gather Turbo Pascal eventually went on to become Delphi, which was 
briefly very successful. I believe that really was a full OO system.


Post a reply to this message

From: Warp
Subject: Re: Living in a box
Date: 23 Apr 2012 10:32:08
Message: <4f9567e7@news.povray.org>
Invisible <voi### [at] devnull> wrote:
> It came out around the time OOP was the latest crazy, and everything 
> that wasn't OO was old and obsolete, and OO was the wave of the future. 
> So they took the existing language, bolted on a few very superficially 
> OO syntax elements, and said "Hey! Look! Our product is OO now! BUY IT!!"

  Criticism of the overhyping of object-oriented programming is nothing new.
A famous paper named "My cat is object-oriented" was published in 1989.
(The title is a jab at the fact that anything that claims to be "object-
oriented" sells better, thus if you are selling your cat...)

> About the only /useful/ thing it actually added was a per-type namespace 
> for methods. What's it, really. You could /already/ group code and data 
> together using modules, so the mere syntactic ability to write one 
> inside the other isn't much of a big deal.

  No, what object-oriented programming added was inheritance and
polymorphism. Modules (complete with member functions, public and
private sections, module instantiation and references) existed before
object-oriented programming. What OOP added was inheritance, dynamic
binding and the ability to handle objects polymorphically.

  There are some applications where OOP fits like a glove (eg. GUI
programming), but in most situations just the modular part of OOP is
more than enough.

-- 
                                                          - Warp


Post a reply to this message

From: Warp
Subject: Re: Living in a box
Date: 23 Apr 2012 10:37:55
Message: <4f956943@news.povray.org>
clipka <ano### [at] anonymousorg> wrote:
> There is no language that "is OOP". OOP is a software design approach; 
> An OO language (or OO language feature) is one that helps you implement 
> such a design, but nothing more.

  Do not confuse the terms "object-oriented programming" (OOP),
"object-oriented design" (OOD) and "object oriented programming language".

  OOD is the process of dividing the problem into logical parts,
each part being a class, and establishing their relationships and
dependendcies (inheritance, composition, function calls...) This is
a language-agnostic process.

  OOP is the process of implementing that design in an actual language,
of actually writing code.

  An object-oriented language is a programming language that supports
the necessary features for OOP natively.

> Bundling record data and related functions (aka methods) in a single 
> thing called "class" does help you write software that makes use of data 
> encapsulation (an OOP concept); it doesn't help you with enforcing the 
> rules of encapsulation, but it simplifies the syntax by (1) 
> automatically passing the ubiquitous "this" pointer, and (2) adding new 
> namespaces to avoid naming collisions. As such, it does qualify as an OO 
> language feature.

  Just because a language offers *some* features that are intrinsic
to object-oriented programming doesn't make the language automatically
an OO language.

-- 
                                                          - Warp


Post a reply to this message

From: Invisible
Subject: Re: Living in a box
Date: 23 Apr 2012 11:06:41
Message: <4f957001$1@news.povray.org>
>> "Hey! Look! Our product is OO now! BUY IT!!"
>
>    Criticism of the overhyping of object-oriented programming is nothing new.

It just irks me when people take a concept, produce a superficial 
semblance of it, and then claim that as the genuine article. Borland 
took the idea of OOP and added some trivial syntactic changes which give 
the illusion of extra power, without actually offering any.

> A famous paper named "My cat is object-oriented" was published in 1989.
> (The title is a jab at the fact that anything that claims to be "object-
> oriented" sells better, thus if you are selling your cat...)

Required XKCD quote: http://www.xkcd.com/26/

>> About the only /useful/ thing it actually added was a per-type namespace
>> for methods. What's it, really. You could /already/ group code and data
>> together using modules, so the mere syntactic ability to write one
>> inside the other isn't much of a big deal.
>
>    No, what object-oriented programming added was inheritance and
> polymorphism. Modules (complete with member functions, public and
> private sections, module instantiation and references) existed before
> object-oriented programming. What OOP added was inheritance, dynamic
> binding and the ability to handle objects polymorphically.
>
>    There are some applications where OOP fits like a glove (eg. GUI
> programming), but in most situations just the modular part of OOP is
> more than enough.

You can write modules in Pascal. The functions within them can be public 
or private. The types can also be public or private.

However, if a type is public, its entire internal structure must also be 
public. (That includes any types it mentions.) Similarly, any type which 
is an argument or result type to a public function must be public.

If they had removed these artificial limitations, that would have been 
/far/ more useful than just changing the "record" keyword to "class". :-P

(Indeed, that's what Haskell does: You can make a type public, but keep 
its internal structure private. And then only functions in that module 
can access the internal structure. And that's how you do encapsulation.)


Post a reply to this message

From: Invisible
Subject: Re: Living in a box
Date: 23 Apr 2012 11:08:30
Message: <4f95706e$1@news.povray.org>
On 23/04/2012 03:37 PM, Warp wrote:

>    OOD is the process of dividing the problem into logical parts,
> each part being a class, and establishing their relationships and
> dependendcies (inheritance, composition, function calls...) This is
> a language-agnostic process.

Ah yes... Now I remember back to my days at university, learning about 
UML and so forth. Great days. Heh. :-S

At any rate, any language where you literally CANNOT DO runtime binding 
strikes me as not being very OO. (As I say, Pascal doesn't even have 
function pointers, so it's not like you can fake it yourself. You're 
just STUCK...)


Post a reply to this message

From: clipka
Subject: Re: Living in a box
Date: 23 Apr 2012 17:58:34
Message: <4f95d08a$1@news.povray.org>
Am 23.04.2012 16:37, schrieb Warp:

>    Do not confuse the terms "object-oriented programming" (OOP),
> "object-oriented design" (OOD) and "object oriented programming language".
>
>    OOD is the process of dividing the problem into logical parts,
> each part being a class, and establishing their relationships and
> dependendcies (inheritance, composition, function calls...) This is
> a language-agnostic process.
>
>    OOP is the process of implementing that design in an actual language,
> of actually writing code.
>
>    An object-oriented language is a programming language that supports
> the necessary features for OOP natively.

That would qualify Assembler and C as object-oriented: They both 
natively support /all/ features that are really /necessary/ for OOP 
(actually for /every/ concept commonly associated with OOP). You /can/ 
do OOP with plain old ANSI C. (As a matter of fact, C++ started out as a 
meta-language to simplify object-oriented programming in C; the very 
first C++ compilers actually generated C code.)

I'd say, an object-oriented language is a language that provides 
syntactic sugar specifically for OO concepts. Syntactic sugar isn't a 
/necessary/ feature for OOP though.


>    Just because a language offers *some* features that are intrinsic
> to object-oriented programming doesn't make the language automatically
> an OO language.

Does a language have to provide syntactic sugar for /all/ OO concepts, 
in order to claim the label "OO language"? I don't think so. Multiple 
inheritance, for instance, is a concept supported by only very few 
languages. Interfaces are a concept supported by some, but not by 
others. Some languages don't support code inheritance. Virtually no 
language supports both static and dynamic inheritance.

So ultimately the question boils down to what consitutes the /minimum/ 
set of OO concepts a language must provide syntactic sugar for in order 
to claim the "OO" label. I don't think such a set exists.


BTW, I just had a look in the 'net: Turbo-Pascal 5.5 /did/ support 
virtual methods (and thus, obviously, polymorphism). See 
http://edn.embarcadero.com/article/images/20803/TP_55_OOP_Guide.pdf for 
more details on TP 5.5's OOP extensions.


Post a reply to this message

From: Darren New
Subject: Re: Living in a box
Date: 25 Apr 2012 01:08:46
Message: <4f9786de$1@news.povray.org>
On 4/23/2012 1:05, Invisible wrote:
>> There are lots of languages that let you can pass a function as an
>> argument.
>
> Heh. I bet most of them are scripting languages though. :-P

Not really. Arguably, even C allows it, C++, C# allows a delegate which is 
essentially the same thing, and yes, bunches of interpreted languages.

-- 
Darren New, San Diego CA, USA (PST)
   "Oh no! We're out of code juice!"
   "Don't panic. There's beans and filters
    in the cabinet."


Post a reply to this message

From: Darren New
Subject: Re: High theory
Date: 25 Apr 2012 01:13:40
Message: <4f978804@news.povray.org>
On 4/23/2012 3:19, Invisible wrote:
> ∃ i ∈ S: ∀ x ∈ S, i # x = x # i = x
.

I must say it cracks me up that you type things like this and also bitch 

about HTML entities not being part of XML.

-- 
Darren New, San Diego CA, USA (PST)
   "Oh no! We're out of code juice!"
   "Don't panic. There's beans and filters
    in the cabinet."


Post a reply to this message

From: Darren New
Subject: Re: High theory
Date: 25 Apr 2012 01:15:00
Message: <4f978854$1@news.povray.org>
On 4/23/2012 6:50, clipka wrote:
> I suggest thinking outside the box... (sorry, pun definitely intended).
> Call it a wrapper object, and I guess we're fine.

A box is pretty much what everyone calls it. Indeed, languages that do this 
without extra syntax are called "autoboxing" languages. :-)

-- 
Darren New, San Diego CA, USA (PST)
   "Oh no! We're out of code juice!"
   "Don't panic. There's beans and filters
    in the cabinet."


Post a reply to this message

From: Invisible
Subject: Re: Living in a box
Date: 25 Apr 2012 04:07:07
Message: <4f97b0ab$1@news.povray.org>
On 25/04/2012 06:08 AM, Darren New wrote:
> On 4/23/2012 1:05, Invisible wrote:
>>> There are lots of languages that let you can pass a function as an
>>> argument.
>>
>> Heh. I bet most of them are scripting languages though. :-P
>
> Not really. Arguably, even C allows it, C++, C# allows a delegate which
> is essentially the same thing, and yes, bunches of interpreted languages.

C and C++ have function pointers. It's dubious whether functions are 
"first class", but certainly you can pass them as arguments.

C# presumably allows /everything/.

Java allows you to use the reflection API to create an object that 
represents a function method, and to invoke that method. Alternatively 
you can use anonymous inner classes. (The fact that this feature even 
/exists/ tells you how badly Java programmers want anonymous functions.)

Pascal? Forget it.

Eiffel? Well, they have "delegates", which are sort-of the same thing.

Come to think of it, I don't actually /know/ any other compiled languages...

Obviously, any random scripting languages supports eval() and so 
trivially supports first-class functions.


Post a reply to this message

From: Invisible
Subject: Re: High theory
Date: 25 Apr 2012 04:09:28
Message: <4f97b138$1@news.povray.org>
On 25/04/2012 06:13 AM, Darren New wrote:
> On 4/23/2012 3:19, Invisible wrote:
>> ∃ i ∈ S: ∀ x ∈ S, i # x = x # i = x.
>
> I must say it cracks me up that you type things like this and also bitch
> about HTML entities not being part of XML.

How do you think I got access to the symbols in the first place? I wrote 
an HTML document with the right entities in it, loaded it into Firefox 
and I was then able to copy and paste them into Thunderbird.

Interestingly, when you put non-ASCII characters into an NNTP post, it 
actually works. When you write them into an XML document, it fails 
horribly. (In fact, not even non-ASCII. The £ symbol tends to go wrong 
too...)


Post a reply to this message

From: Le Forgeron
Subject: Re: High theory
Date: 25 Apr 2012 07:40:11
Message: <4f97e29b$1@news.povray.org>
Le 23/04/2012 12:19, Invisible a écrit :
> A magma isn't especially interesting by itself. However, if we add the
> rule that # must be /associative/, then we got a "semigroup".
> 
>   ∀ x, y, z ∈ S, (x # y) # z = x # (y # z).
> 
> Already this begins to have interesting mathematical properties. But if
> we add a special /identity element/, we get a "monoid".
> 
>   ∃ i ∈ S: ∀ x ∈ S, i # x = x # i = x.
> 

Hey, not only you added identity element, but you seems to imply also
(but not really) that its also commutative:

∀ x ∈ S, ∀ y ∈ S, x # y = y # x.

So please be more careful for my poor brain and write instead:

∃ i ∈ S: ∀ x ∈ S, i # x = x and x # i = x.

There is commutativity for the identity element, but it is not needed to
be commutative.

> If you now take your monoid and give every element a corresponding
> /inverse element/, then you have a "group".
> 
>   ∀ x ∈ S, ∃ y ∈ S: x # y = y # x = i.

Your definition of inverse element once again seems to imply general
commutativity, it is not needed.

(I like to think about the Quaternion group (non abelian group of order
8): 1 & -1 are their own inverse, but inverse of i,j,k are same negative
(-i, -j, -k))

Yes, -i.i = i.-i = 1
but i.j = -j.i = k


Post a reply to this message

From: Warp
Subject: Re: Living in a box
Date: 25 Apr 2012 08:09:43
Message: <4f97e987@news.povray.org>
clipka <ano### [at] anonymousorg> wrote:
> >    An object-oriented language is a programming language that supports
> > the necessary features for OOP natively.

> That would qualify Assembler and C as object-oriented: They both 
> natively support /all/ features that are really /necessary/ for OOP 
> (actually for /every/ concept commonly associated with OOP).

  I can't fathom how you are understanding my sentence as meaning the
*exact opposite* of what it's saying.

  Assembler and C are precisely *not* OOP languages because they do *not*
have any kind of native support for OOP features. If you want any kind of
object-oriented programming, you'll have to hack those features manually
because the languages themselves offer no support whatsoever.

> You /can/ do OOP with plain old ANSI C.

  So what? That doesn't make it an OOP language.

> I'd say, an object-oriented language is a language that provides 
> syntactic sugar specifically for OO concepts. Syntactic sugar isn't a 
> /necessary/ feature for OOP though.

  I said in my post "do not confuse object-oriented programming with an
object-oriented programming language", and you are doing exactly that.

-- 
                                                          - Warp


Post a reply to this message

From: Francois Labreque
Subject: Re: High theory
Date: 25 Apr 2012 08:33:56
Message: <4f97ef34$1@news.povray.org>
Le 2012-04-25 04:09, Invisible a écrit :
> On 25/04/2012 06:13 AM, Darren New wrote:
>> On 4/23/2012 3:19, Invisible wrote:
>>> ∃ i ∈ S: ∀ x ∈ S, i # x = x # i = x.
>>
>> I must say it cracks me up that you type things like this and also bitch
>> about HTML entities not being part of XML.
>
> How do you think I got access to the symbols in the first place? I wrote
> an HTML document with the right entities in it, loaded it into Firefox
> and I was then able to copy and paste them into Thunderbird.
>
> Interestingly, when you put non-ASCII characters into an NNTP post, it
> actually works. When you write them into an XML document, it fails
> horribly. (In fact, not even non-ASCII. The £ symbol tends to go wrong
> too...)

That's because Thunderbird changed them to UTF-8, because you told it to 
do so in the account options dialog box.

...

Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable

...

On 4/23/2012 3:19, Invisible wrote:
 > =E2=88=83 i =E2=88=88 S: =E2=88=80 x =E2=88=88 S, i # x =3D x # i =3D x=
=2E


-- 
/*Francois Labreque*/#local a=x+y;#local b=x+a;#local c=a+b;#macro P(F//
/*    flabreque    */L)polygon{5,F,F+z,L+z,L,F pigment{rgb 9}}#end union
/*        @        */{P(0,a)P(a,b)P(b,c)P(2*a,2*b)P(2*b,b+c)P(b+c,<2,3>)
/*   gmail.com     */}camera{orthographic location<6,1.25,-6>look_at a }


Post a reply to this message

From: Invisible
Subject: Re: High theory
Date: 25 Apr 2012 09:07:28
Message: <4f97f710$1@news.povray.org>
>>    ∃ i ∈ S: ∀ x ∈ S, i # x = x # i = x.
>
> Hey, not only you added identity element, but you seems to imply also
> (but not really) that its also commutative:
>
> ∀ x ∈ S, ∀ y ∈ S, x # y = y # x.
>
> So please be more careful for my poor brain and write instead:
>
> ∃ i ∈ S: ∀ x ∈ S, i # x = x and x # i = x.
>
> There is commutativity for the identity element, but it is not needed to
> be commutative.

A monoid is /defined as/ having a two-sided identity.

Note that it is possible to have more than one left-identity, OR to have 
more than one right-identity. But it is impossible to have a 
left-identity and a distinct right-identity.

Suppose that

   ∃ i ∈ S: ∀ x ∈ S, i # x = x
   ∃ j ∈ S: ∀ x ∈ S, x # j = x

are the left and right identities of #. Now consider the term i#j. By 
the first equation, i#j=j. By the second equation i#j=i. Thus we have 
that i = j.

> Your definition of inverse element once again seems to imply general
> commutativity, it is not needed.

Again, a group is /defined as/ having two-sided inverses.

If you wish to split hairs, you don't actually need to /insist/ that the 
inverses by double-sided; the associativity of # and the existence of a 
two-sided inverse i already necessarily implies this fact:

Consider the term

   x # y # x

where y is the left-inverse of x. By that assumption, we have

   (x # y) # x = i # x

and by the definition of i as the two-sided identity, we have

   (x # y) # x = i # x = x

By the assumption of associativity, we have that

   (x # y) # x = x # (y # x)

It immediately follows that y # x must be the identity, and hence that y 
is ALSO the right-inverse of x. QED.

> (I like to think about the Quaternion group (non abelian group of order
> 8): 1&  -1 are their own inverse, but inverse of i,j,k are same negative
> (-i, -j, -k))

OK, so 1 is the identity element, -i is the inverse of i, -j is the 
inverse of j, and -k is the inverse of k.

> Yes, -i.i = i.-i = 1
> but i.j = -j.i = k

That is true - but irrelevant. You just proved that the group is 
non-Abelian. We know that. We're discussing the /inverses/ though, and 
if you look, we have:

   i . -i = 1 = -i . i
   j . -j = 1 = -j . j
   k . -k = 1 = -k . k

In other words, -i is the TWO-SIDED inverse of i, and so on and so forth 
- as I originally asserted.

Every term commutes with the identity and with its own inverse. It might 
not commute with anything else, but it does commute with these two 
special elements.


Post a reply to this message

From: andrel
Subject: Re: I'm in the mood for monads
Date: 25 Apr 2012 11:00:38
Message: <4F981195.4070106@gmail.com>
On 22-4-2012 12:40, Warp wrote:
> Orchid Win7 v1<voi### [at] devnull>  wrote:
>>> For instance,
>>> I still don't understand what currying *really* is about, and every time
>>> I try to suggest "is like this?" the answer is "not really".
>
>> 1. You can take a 5-argument function, pass it 2 argument, and get a
>> 3-argument function as the result.
>
>    But that's the thing: It sounds so trivial as to defy sense. Why give
> a particular name to such a trivial thing? It's like calling the act of
> taking a 3-dimensional vector and expanding it to a 4-dimensional one
> "potatoing", or taking two integers and adding them together "bananaing",
> or taking a class and adding another class as its member "orangeing".
> Why give an obscure name to such a trivial operation?
>
>    But then when one starts asking questions like "so it's like giving
> default values to function parameters?" or "so it's like writing another
> function with less parameters that calls the first function by giving it
> some default values as the rest of the parameters?", the answer is something
> like "not really".

My answers to why currying is important is that
- if you have currying, you have function application. if you have a one 
input function and you supply that input you reduce it to a zero 
argument function a.k.a. a constant. If you think about it that way the 
distinction between a value and a function gets blurred.
- I think that one of the main reasons to give it a name is that when 
the concept was invented you suddenly had (non-exotic) functions that 
could take functions as argument and return yet another function. In 
short it is when functions transformed from recipes to objects.

When you have done OO languages for some time you might not see the 
point anymore, that does not mean that at one point in time you made the 
mental transition yourself.


-- 
tip: do not run in an unknown place when it is too dark to see the 
floor, unless you prefer to not use uppercase.


Post a reply to this message

From: nemesis
Subject: Re: I'm in the mood for monads
Date: 25 Apr 2012 13:58:03
Message: <4f983b2b@news.povray.org>
Warp escreveu:
> clipka <ano### [at] anonymousorg> wrote:
>> So yes: Currying *is* like writing a function that takes fewer 
>> arguments, calling the original one and supplying (unchangeable) 
>> defaults for the missing arguments.
> 
>   I think that the difference is that the new function is not static,
> but it's generated dynamically. (In other words, what you end up is a
> new function which fixes some of the parameters of the original function,
> but the values to which they are fixed is determined at runtime rather
> than at compile time.)
> 
>   This means, if I understand correctly, that you could for example create
> such functions in a loop (or, as we are talking about functional languages,
> in a recursive manner), which is quite difficult to achieve with static,
> compile-time functions. (I suppose you could try to emulate this in a
> statically typed language with no lambda functions, but you would need
> some kind of stack or something where the fixed parameter values are
> stored.)
> 
>   There are probably even deeper implications.

currying comes from Haskell Curry, the mathematician behind many further 
lambda calculus concepts.

Here's the thing about the lambda calculus, which is at the kernel of 
haskell the language:  all the functions are one-argument functions that 
return other one-argument functions.  So, multiple argument functions 
are actually just syntatic sugar for convenience.  And yes, clearly 
syntatic sugar is a good thing, as any competent C++ template writer can 
attest.

Surely writing a function and letting the compiler handle all the 
partial applications is much saner than writing yourself functions for 
each possible partial application case.  And no, I don't think in 
haskell such functions are dynamically generated.  Like I said, the 
concept of one-argument functions is at the very heart of haskell:  the 
compiler breaks all functions down into one-argument functions, at 
compile time.

Then again, in languages with default and keyword arguments you do not 
need to worry about that, only to remember the argument names.  Argument 
position, names or order, though, can still shoot everyone in the foot.

-- 
a game sig: http://tinyurl.com/d3rxz9


Post a reply to this message

From: clipka
Subject: Re: Living in a box
Date: 25 Apr 2012 14:09:43
Message: <4f983de7$1@news.povray.org>
Am 25.04.2012 10:07, schrieb Invisible:
> On 25/04/2012 06:08 AM, Darren New wrote:
>> On 4/23/2012 1:05, Invisible wrote:
>>>> There are lots of languages that let you can pass a function as an
>>>> argument.
>>>
>>> Heh. I bet most of them are scripting languages though. :-P
>>
>> Not really. Arguably, even C allows it, C++, C# allows a delegate which
>> is essentially the same thing, and yes, bunches of interpreted languages.
>
> C and C++ have function pointers. It's dubious whether functions are
> "first class", but certainly you can pass them as arguments.
>
> C# presumably allows /everything/.
>
> Java allows you to use the reflection API to create an object that
> represents a function method, and to invoke that method. Alternatively
> you can use anonymous inner classes. (The fact that this feature even
> /exists/ tells you how badly Java programmers want anonymous functions.)
>
> Pascal? Forget it.

Turbo Pascal? Definitely yes, as I mentioned before!


Post a reply to this message

From: Warp
Subject: Re: I'm in the mood for monads
Date: 25 Apr 2012 16:01:10
Message: <4f985806@news.povray.org>
nemesis <nam### [at] gmailcom> wrote:
> Here's the thing about the lambda calculus, which is at the kernel of 
> haskell the language:  all the functions are one-argument functions that 
> return other one-argument functions.  So, multiple argument functions 
> are actually just syntatic sugar for convenience.

  But what's the advantage in having only one-argument functions?

-- 
                                                          - Warp


Post a reply to this message

From: Orchid Win7 v1
Subject: Re: Living in a box
Date: 25 Apr 2012 16:18:47
Message: <4f985c27$1@news.povray.org>
>> Pascal? Forget it.
>
> Turbo Pascal? Definitely yes, as I mentioned before!

OK, but that's not really the classic Pascal of old.

The same probably goes for Delphi, which [I gather] is a further 
extension of Turbo Pascal.

In a similar was, AMOS BASIC has local variables, named functions and 
procedures, separate compilation, and a whole chock-load of features. In 
fact, so many features that it hardly counts as "BASIC" any more; it's 
more like a brand new language with a superficial resemblance to BASIC...


Post a reply to this message

From: Orchid Win7 v1
Subject: Re: I'm in the mood for monads
Date: 25 Apr 2012 16:24:48
Message: <4f985d90$1@news.povray.org>
On 25/04/2012 09:01 PM, Warp wrote:
> nemesis<nam### [at] gmailcom>  wrote:
>> Here's the thing about the lambda calculus, which is at the kernel of
>> haskell the language:  all the functions are one-argument functions that
>> return other one-argument functions.  So, multiple argument functions
>> are actually just syntatic sugar for convenience.
>
>    But what's the advantage in having only one-argument functions?

If you're writing a mathematical theory about which computations are 
possible, then only having to worry about 1-arg functions makes the 
theory simpler. That's why the lambda calculus does it that way.

If you're trying to write a real program to run on a real computer, 
that's another matter.

It's useful to be able to quickly throw together a new function by just 
writing a partial call to an existing one. The easiest way to implement 
that is to consider every function to be a 1-arg function.

Aside from a couple of other conveniences, it also allows you to process 
functions of variable numbers of arguments in a uniform way: Keep adding 
arguments, one at a time, until it's full.

There's nothing deeply fundamental or sacred about 1-arg functions. They 
just have a couple of useful properties, that's all.


Post a reply to this message

From: nemesis
Subject: Re: I'm in the mood for monads
Date: 25 Apr 2012 16:42:01
Message: <4f986199@news.povray.org>
Warp escreveu:
> nemesis <nam### [at] gmailcom> wrote:
>> Here's the thing about the lambda calculus, which is at the kernel of 
>> haskell the language:  all the functions are one-argument functions that 
>> return other one-argument functions.  So, multiple argument functions 
>> are actually just syntatic sugar for convenience.
> 
>   But what's the advantage in having only one-argument functions?

seemingly, automatic currying.

-- 
a game sig: http://tinyurl.com/d3rxz9


Post a reply to this message

From: Warp
Subject: Re: I'm in the mood for monads
Date: 25 Apr 2012 17:02:31
Message: <4f986667@news.povray.org>
Orchid Win7 v1 <voi### [at] devnull> wrote:
> On 25/04/2012 09:01 PM, Warp wrote:
> > nemesis<nam### [at] gmailcom>  wrote:
> >> Here's the thing about the lambda calculus, which is at the kernel of
> >> haskell the language:  all the functions are one-argument functions that
> >> return other one-argument functions.  So, multiple argument functions
> >> are actually just syntatic sugar for convenience.
> >
> >    But what's the advantage in having only one-argument functions?

> If you're writing a mathematical theory about which computations are 
> possible, then only having to worry about 1-arg functions makes the 
> theory simpler. That's why the lambda calculus does it that way.

  I can believe that. However, what I was really asking was what's the
advantage of having only one-argument functions in a practical programming
language.

> It's useful to be able to quickly throw together a new function by just 
> writing a partial call to an existing one.

  That seems to be a very specialized case. There are tons of other
combinations (eg. in terms of the number of parameters to a function,
among many other things) that can be equally useful.

-- 
                                                          - Warp


Post a reply to this message

From: Orchid Win7 v1
Subject: Re: High theory
Date: 25 Apr 2012 17:12:24
Message: <4f9868b8$1@news.povray.org>
>> There is commutativity for the identity element, but it is not needed to
>> be commutative.
>
> A monoid is /defined as/ having a two-sided identity.

I had hoped to prove that the associativity of # implies the 
two-sidedness of any identity element. Instead, somebody showed me a 
counter-example:

If we define # as

   ∀ x, y ∈ S, x # y = y

then every element of S is trivially a left-identity, and no 
right-identity exists. Miraculously, this operator is also associative:

   x # y # z
   (x # y) # z = y # z = z
   x # (y # z) = x # z = z

So it seems it /is/ perfectly possible for a semigroup to have one or 
more one-sided inverses - it's just that they all have to be /the same/ 
side. A monoid, on the other hand, is /defined as/ having a two-sided 
inverse, as I originally asserted.


Post a reply to this message

From: Orchid Win7 v1
Subject: Re: I'm in the mood for monads
Date: 25 Apr 2012 17:16:22
Message: <4f9869a6$1@news.povray.org>
>> If you're writing a mathematical theory about which computations are
>> possible, then only having to worry about 1-arg functions makes the
>> theory simpler. That's why the lambda calculus does it that way.
>
>    I can believe that. However, what I was really asking was what's the
> advantage of having only one-argument functions in a practical programming
> language.

Sure, I get that. I was just adding a point of context.

>> It's useful to be able to quickly throw together a new function by just
>> writing a partial call to an existing one.
>
>    That seems to be a very specialized case. There are tons of other
> combinations (eg. in terms of the number of parameters to a function,
> among many other things) that can be equally useful.

You'll notice that Haskell programmers are very particular about the 
order in which a function takes its arguments - because, as you say, you 
can only partially apply the functions IN ORDER.

Haskell has one sole exception to this: Binary operators can be curried 
in any order. So (5/) and (/5) are both valid functions (and, you'll 
notice, have different meanings).

If it's /really/ a problem, it's utterly trivial to write a tiny little 
lambda function to set one of the arguments in the middle of the 
argument list. Currying is just a handy short-cut in that instance.

As I say, the only "really powerful" thing about currying is the ability 
to polymorphically handle multi-argument functions. Other than that, 
it's just a handy short-cut.


Post a reply to this message

From: Warp
Subject: Re: Living in a box
Date: 25 Apr 2012 17:18:27
Message: <4f986a23@news.povray.org>
Orchid Win7 v1 <voi### [at] devnull> wrote:
> In a similar was, AMOS BASIC has local variables, named functions and 
> procedures, separate compilation, and a whole chock-load of features. In 
> fact, so many features that it hardly counts as "BASIC" any more; it's 
> more like a brand new language with a superficial resemblance to BASIC...

  If I recall correctly, the original BASIC, and the vast majority of
clones for a pretty long time, didn't even have the concept of a function.
They had subroutines (the most typical keyword to jump to one being GOSUB)
which were just slightly fancier GOTO labels.

  Every single variable was global, of course. (No such thing as a variable
local to a subroutine.)

  And forget about modules and separate source files for subroutines.
The whole program was always in one single file. (Heck, even the concept
of "file" was not really well-defined in the age of punch cards and magnetic
tapes.)

  The only control structure other than GOTO was an IF (and you were lucky
if your brand of BASIC supported an ELSE branch.) Anything that couldn't be
done with IF had to be done with GOTO.

  And the language was completely untyped, of course. Typically you could
have two types: An integral (usually floating point) and a string. That's
about it. Some variants possibly supported some kind of array or enumeration
structure. Forget about creating your own types or data containers.

  Also, originally every single line was numbered. Typically the line numbers
were in increments of 10 so that you could add additional lines between two
existing lines. If you kept adding lines between two existing lines, you
would eventually run out of line numbers and you were stuck, and would have
to start re-numbering lines manually. (The fanciest BASIC editors had a way
of re-numbering the whole program to be once again in increments of 10. Of
course this messed up any numbering scheme you might have had, eg. subroutine
1 starting from line 1000, subroutine 2 starting from line 2000 and so on.
The automatic re-numbering would just make every line number be 10 apart
from each other.)

  More modern BASIC variants got rid of mandatory line numbers, and started
supporting named labels as well as actual functions, arrays, dividing the
program into several source files, new control structures, and other fancy
stuff.

-- 
                                                          - Warp


Post a reply to this message

From: andrel
Subject: Re: I'm in the mood for monads
Date: 25 Apr 2012 18:03:00
Message: <4F987491.3040102@gmail.com>
On 25-4-2012 19:58, nemesis wrote:
> Warp escreveu:
>> clipka <ano### [at] anonymousorg> wrote:
>>> So yes: Currying *is* like writing a function that takes fewer
>>> arguments, calling the original one and supplying (unchangeable)
>>> defaults for the missing arguments.
>>
>> I think that the difference is that the new function is not static,
>> but it's generated dynamically. (In other words, what you end up is a
>> new function which fixes some of the parameters of the original function,
>> but the values to which they are fixed is determined at runtime rather
>> than at compile time.)
>>
>> This means, if I understand correctly, that you could for example create
>> such functions in a loop (or, as we are talking about functional
>> languages,
>> in a recursive manner), which is quite difficult to achieve with static,
>> compile-time functions. (I suppose you could try to emulate this in a
>> statically typed language with no lambda functions, but you would need
>> some kind of stack or something where the fixed parameter values are
>> stored.)
>>
>> There are probably even deeper implications.
>
> currying comes from Haskell Curry, the mathematician behind many further
> lambda calculus concepts.
>
> Here's the thing about the lambda calculus, which is at the kernel of
> haskell the language: all the functions are one-argument functions that
> return other one-argument functions. So, multiple argument functions are
> actually just syntatic sugar for convenience. And yes, clearly syntatic
> sugar is a good thing, as any competent C++ template writer can attest.
>
> Surely writing a function and letting the compiler handle all the
> partial applications is much saner than writing yourself functions for
> each possible partial application case. And no, I don't think in haskell
> such functions are dynamically generated. Like I said, the concept of
> one-argument functions is at the very heart of haskell: the compiler
> breaks all functions down into one-argument functions, at compile time.

IIRC in (compilers for) languages like Miranda lambda calculus is first 
converted to Combinatory Logic (another branch of mathematics that is 
provable equivalent to Lambda Calculus). Where CL is extended to include 
many other operators (including the standard mathematical operators like 
addition and multiplication) apart from the usual S,K, and I. The 
advantage is that CL is more efficient to implement and LC has better 
properties as a language to express problems.

> Then again, in languages with default and keyword arguments you do not
> need to worry about that, only to remember the argument names. Argument
> position, names or order, though, can still shoot everyone in the foot.
>

Shooting yourself in the foot is generally less of a problem than the 
urge to shoot oneself in the head.


-- 
tip: do not run in an unknown place when it is too dark to see the 
floor, unless you prefer to not use uppercase.


Post a reply to this message

From: Darren New
Subject: Re: I'm in the mood for monads
Date: 25 Apr 2012 23:42:10
Message: <4f98c412$1@news.povray.org>
On 4/25/2012 13:01, Warp wrote:
>    But what's the advantage in having only one-argument functions?

The same advantage as not having writable code and only having a linear tape 
gives to Turing machines. It makes the math easier, is all. You're not 
supposed to actually *compute* with it, any more than you're supposed to run 
business logic on a TM.

-- 
Darren New, San Diego CA, USA (PST)
   "Oh no! We're out of code juice!"
   "Don't panic. There's beans and filters
    in the cabinet."


Post a reply to this message

From: Darren New
Subject: Re: Living in a box
Date: 25 Apr 2012 23:49:08
Message: <4f98c5b4$1@news.povray.org>
On 4/25/2012 1:07, Invisible wrote:
> C and C++ have function pointers. It's dubious whether functions are "first
> class", but certainly you can pass them as arguments.

Given that the only levels of context in C is "global" and "auto", one could 
even argue that a function pointer in C is actually a closure, as it 
succeeds in capturing every variable in the scope of the function. ;-)

> C# presumably allows /everything/.

Not sure what that means. You *can* create functions on the fly in C#, so 
yeah, I don't think there's much you can't do with enough work.

> Java allows you to use the reflection API to create an object that
> represents a function method, and to invoke that method. Alternatively you
> can use anonymous inner classes. (The fact that this feature even /exists/
> tells you how badly Java programmers want anonymous functions.)

Anonymous inner classes aren't functions. They're classes you instantiate.

> Eiffel? Well, they have "delegates", which are sort-of the same thing.

I'm not sure what's "sort of" about them. You can create a new function, 
create a delegate to it, assign it to a variable, send it over a network 
connection, and invoke the function.

-- 
Darren New, San Diego CA, USA (PST)
   "Oh no! We're out of code juice!"
   "Don't panic. There's beans and filters
    in the cabinet."


Post a reply to this message

From: Darren New
Subject: Re: Living in a box
Date: 25 Apr 2012 23:53:28
Message: <4f98c6b8@news.povray.org>
On 4/25/2012 14:18, Warp wrote:
>    If I recall correctly, the original BASIC, and the vast majority of
> clones for a pretty long time, didn't even have the concept of a function.

Correct. Raise your hand if you've written Dartmouth BASIC.   _O/

> They had subroutines (the most typical keyword to jump to one being GOSUB)
> which were just slightly fancier GOTO labels.

Yep.

>    The only control structure other than GOTO was an IF (and you were lucky
> if your brand of BASIC supported an ELSE branch.) Anything that couldn't be
> done with IF had to be done with GOTO.

No, there was FOR/NEXT. I don't think there was a WHILE.  The THEN was a 
line number, not a statement.

>    And the language was completely untyped, of course. Typically you could
> have two types: An integral (usually floating point) and a string. That's
> about it.

There were strings and integers, yes.

> Some variants possibly supported some kind of array or enumeration
> structure. Forget about creating your own types or data containers.

They all had arrays. Lots of the original 8-bit BASIC interpreters had one 
array of integers that basically filled all the extra memory.

>    Also, originally every single line was numbered.

Indeed. And this is because there was no defined editor. You could type 
lines into BASIC and edit your program using nothing but the interpreter.

-- 
Darren New, San Diego CA, USA (PST)
   "Oh no! We're out of code juice!"
   "Don't panic. There's beans and filters
    in the cabinet."


Post a reply to this message

From: Invisible
Subject: Re: Living in a box
Date: 26 Apr 2012 04:30:08
Message: <4f990790$1@news.povray.org>
On 25/04/2012 10:18 PM, Warp wrote:
> Orchid Win7 v1<voi### [at] devnull>  wrote:
>> In a similar was, AMOS BASIC has local variables, named functions and
>> procedures, separate compilation, and a whole chock-load of features. In
>> fact, so many features that it hardly counts as "BASIC" any more; it's
>> more like a brand new language with a superficial resemblance to BASIC...
>
>    If I recall correctly, the original BASIC, and the vast majority of
> clones for a pretty long time, didn't even have

C64 BASIC is the very first programming language I ever learned, when I 
was still only 9 years old. (I soon learned many other dialects.)

The language is interpreted, not compiled. "Files" are stored on tape, 
so random access is impossible, and splitting a program across several 
files would be a pointless endeavour.

There is no text editor. Instead you edit the program using line 
numbers. Type in a command and it executes immediately. (So the BASIC 
interpreter is also the "operating system" as such.) Type in a line 
number followed by a command, and that line is added to the program. 
Lines are kept in sorted order, so you can insert between lines 
(provided their numbers are not consecutive). For this reason, lines are 
invariably numbered in 10s. Enter a line number that already exists, and 
the existing line is replaced. Enter a line number with nothing 
following it, and the line is deleted. The LIST command shows you the 
program listing as it currently exists.

There are three types of variable. Normal variables hold signed 
integers. (I have no idea what their range is.) Variable names ending 
with "#" hold floating-point values. (Remember, no FPU, so SLOOOW. Also, 
64KB of RAM, so these eat memory like candy.) Variable names ending with 
"$" hold variable-length text strings. Typically a string cannot be more 
than 255 characters. Typically a variable name cannot be more than 30 
characters - which is fine. The entire screen is only 40 characters 
wide. (A few BASIC implementations allow up to 30 characters, BUT IGNORE 
ANYTHING BEYOND 8!)

All variables are global variables.

There are no subroutines. There is only GOTO and GOSUB/RETURN. This is 
an UNSTRUCTURED programming language, after all.

You can have multi-dimensional arrays. They all start at index 1. There 
are no user-defined data types.

Your flow control constructs are IF/THEN/ELSE, WHILE/LOOP, REPEAT/UNTIL, 
and FOR/NEXT. Some dialects allow compound statements on a single line 
using ":" as separator. Others demand that you use THEN GOTO if you want 
multiple statements.

Almost every dialect had a strange DATA construct. A DATA statement is 
followed by a comma-separated list of decimal numbers. The READ 
statement fetches the next code into the specified variable. The RESTORE 
command resets to the first DATA statement. If you want to write machine 
code, you invariably have to write a BASIC program such as

10 FOR X = 1 TO 13
20   READ D
30   POKE (23874+X), D
40 NEXT X
50 DATA 45,84,27,45,95,13,75,65,42,84,13,10,59

This uses the POKE command to copy the stuff in the DATA statements into 
a given location in RAM. (Notice how the DATA statements accept only 
decimal. In general, BASIC understands nothing else.) This is arguably 
the only reason that I know that the op-code for the 6510 "RTS" (return 
from subroutine) command is 96 decimal.

To my mind, any language more sophisticated than this is no longer 
"BASIC". It is now "a language based on BASIC".


Post a reply to this message

From: Francois Labreque
Subject: Re: Living in a box
Date: 26 Apr 2012 08:08:12
Message: <4f993aac$1@news.povray.org>
Le 2012-04-26 04:30, Invisible a écrit :
> Almost every dialect had a strange DATA construct. A DATA statement is
> followed by a comma-separated list of decimal numbers. The READ
> statement fetches the next code into the specified variable. The RESTORE
> command resets to the first DATA statement. If you want to write machine
> code, you invariably have to write a BASIC program such as
>
> 10 FOR X = 1 TO 13
> 20 READ D
> 30 POKE (23874+X), D
> 40 NEXT X
> 50 DATA 45,84,27,45,95,13,75,65,42,84,13,10,59

Think punch cards.

In the case above, you have 4 cards with your program, one line per 
card, and can change the DATA card every time you run the program.  So 
when your warehouse invetory changes, you can still reuse the "Monthly 
report" program deck of cards with this month's deck of DATA cards.

Historical note: this is also the reason for the line numbers.  It 
allowed the deck to be shuffled (ex: after being dropped on the floor) 
and read by the computer without having to bother about the order of the 
cards.

Of course, on a cassette or a floppy diskette, there is little risk of 
dropping your code on the floor and shuffling the data, so eventually 
line numbers disappeared.


-- 
/*Francois Labreque*/#local a=x+y;#local b=x+a;#local c=a+b;#macro P(F//
/*    flabreque    */L)polygon{5,F,F+z,L+z,L,F pigment{rgb 9}}#end union
/*        @        */{P(0,a)P(a,b)P(b,c)P(2*a,2*b)P(2*b,b+c)P(b+c,<2,3>)
/*   gmail.com     */}camera{orthographic location<6,1.25,-6>look_at a }


Post a reply to this message

From: Warp
Subject: Re: Living in a box
Date: 26 Apr 2012 08:14:16
Message: <4f993c18@news.povray.org>
Darren New <dne### [at] sanrrcom> wrote:
> No, there was FOR/NEXT. I don't think there was a WHILE.  The THEN was a 
> line number, not a statement.

  Right.

  Oh, and forget about indentation. Most "editors" back then had no such
concept. Following deeply nested loops and conditionals was a task in
itself...

-- 
                                                          - Warp


Post a reply to this message

From: Invisible
Subject: Re: Living in a box
Date: 26 Apr 2012 08:17:02
Message: <4f993cbe$1@news.povray.org>
On 26/04/2012 01:14 PM, Warp wrote:
> Darren New<dne### [at] sanrrcom>  wrote:
>> No, there was FOR/NEXT. I don't think there was a WHILE.  The THEN was a
>> line number, not a statement.
>
>    Right.
>
>    Oh, and forget about indentation. Most "editors" back then had no such
> concept. Following deeply nested loops and conditionals was a task in
> itself...

You can't nest IF statements at all.

In every BASIC dialect *I* saw, loop bodies are /automatically/ 
indented, and you can't turn this off.


Post a reply to this message

From: Invisible
Subject: Re: Living in a box
Date: 26 Apr 2012 08:18:36
Message: <4f993d1c$1@news.povray.org>
On 26/04/2012 01:07 PM, Francois Labreque wrote:
> Le 2012-04-26 04:30, Invisible a écrit :
>> Almost every dialect had a strange DATA construct. A DATA statement is
>> followed by a comma-separated list of decimal numbers. The READ
>> statement fetches the next code into the specified variable. The RESTORE
>> command resets to the first DATA statement. If you want to write machine
>> code, you invariably have to write a BASIC program such as
>>
>> 10 FOR X = 1 TO 13
>> 20 READ D
>> 30 POKE (23874+X), D
>> 40 NEXT X
>> 50 DATA 45,84,27,45,95,13,75,65,42,84,13,10,59
>
> Think punch cards.

That's just scary.

But incidentally, most BASIC dialects had a way to read data off tape as 
well. Usually a READ$() function, or sometimes you had to play with CMD 
(change main device) so that your INPUT and PRINT commands now address a 
file rather than the screen...


Post a reply to this message

<<< Previous 43 Messages Goto Initial 50 Messages

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.