 |
 |
|
 |
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> ∃ 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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>>> 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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> 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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Invisible <voi### [at] dev null> 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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
clipka <ano### [at] anonymous org> 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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> "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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
clipka <ano### [at] anonymous org> 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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> ∃ 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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 22-4-2012 12:40, Warp wrote:
> Orchid Win7 v1<voi### [at] dev null> 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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Warp escreveu:
> clipka <ano### [at] anonymous org> 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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
nemesis <nam### [at] gmail com> 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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> 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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 25/04/2012 09:01 PM, Warp wrote:
> nemesis<nam### [at] gmail com> 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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Warp escreveu:
> nemesis <nam### [at] gmail com> 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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Orchid Win7 v1 <voi### [at] dev null> wrote:
> On 25/04/2012 09:01 PM, Warp wrote:
> > nemesis<nam### [at] gmail com> 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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> 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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> 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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Orchid Win7 v1 <voi### [at] dev null> 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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 25-4-2012 19:58, nemesis wrote:
> Warp escreveu:
>> clipka <ano### [at] anonymous org> 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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 25/04/2012 10:18 PM, Warp wrote:
> Orchid Win7 v1<voi### [at] dev null> 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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Darren New <dne### [at] san rr com> 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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 26/04/2012 01:14 PM, Warp wrote:
> Darren New<dne### [at] san rr com> 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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
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
|
 |
|  |
|  |
|
 |
|
 |
|  |
|
 |