Discussion:
The Fact Programming Language
(too old to reply)
map
2011-04-18 01:42:04 UTC
Permalink
I'm rather new to Usenet, so forgive me from barging on in here/
forgetting etiquette/etc.

Since this seems to be the place to do so, I'd decided to follow in
the
footsteps of the great and introduce the world to my programming
language
here.

Over the past two years or so in an effort to learn C I created an
interpreter for a programming language I also developed. The language
is
called FACT, or, Functions Are Classes Too. The basic concept behind
the
language is that classes/objects and functions/scopes can be combined
with
each other, thus creating a combination between the two famous PLT
paradigms (and I know I'm sounding rather pretentious at this point)
procedural and object-oriented programming. If you'd like to jump
right in
to the code, it's released here (I can't figure out how to post
sources on
Usenet): https://github.com/rookieMP/FACT

Moving on, here's the concept explained: Say one where to have a
function
f (). When we call it a new scope is created and by the time it
returns
three local variables are declared within its scope, x, y, and z. Now
lets
say this scope is called S. S contains three elements (as stated
earlier),
x, y and z. We can modify S by accessing these elements and changing
them,
we can even add elements to the scope and add other scopes as well.
But
how to we assign scopes? Let me also mention that each scope (very
much
similar to file systems) contains an "up" and "this" variable. The up
variable points to the next scope upward, and this (as you probably
know)
depends on if the language is lexically or dynamically scoped. The
this
variable points to the current scope. The "this" variable is very much
important for the creation of classes from functions. If a function
were
to return the "this" variable upon completion, it returns essentially
an
object. Methods can be defined by declaring functions withing
functions.

Tell me what you think, I'm very new to this whole game (only 16) but
I
think this language may be rather fruitful (but what do I know? I
already
overuse parentheses, I probably overuse fruitful too . Additionally,
it's a pretty good calculator, using GMP for the variables, and it
supports threading with the sprout statement. It also has a C api,
which
is kind of limited at the current moment, but works. Both 32 and 64
bit
architectures are completely supported; there is no dependency to
either.
In terms of speed, the interpreter is (I think) pretty fast, on my
computer it takes something like 13-14 seconds to computer factorial
of
100000, while python takes around 30-40. These aren't scientific
benchmarks in any sense, but they are promising.

Tell me what you think, if I should bugger off, post this somewhere
else,
whatever. I await your replies!
Pascal J. Bourguignon
2011-04-18 07:41:29 UTC
Permalink
Post by map
Tell me what you think, if I should bugger off, post this somewhere
else, whatever. I await your replies!
The authors of scheme discovered the equivalence between closures and
objects fourty years ago.

http://schemers.org/
--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.
map
2011-04-18 19:28:18 UTC
Permalink
Post by Pascal J. Bourguignon
Post by map
Tell me what you think, if I should bugger off, post this somewhere
else, whatever. I await your replies!
The authors of scheme discovered the equivalence between closures and
objects fourty years ago.
http://schemers.org/
--
__Pascal Bourguignon__                    http://www.informatimago.com/
A bad day in () is better than a good day in {}.
Indeed, however I was curious to know what one would think about a
programming language based on this.
Pascal J. Bourguignon
2011-04-18 20:26:09 UTC
Permalink
Post by map
Post by Pascal J. Bourguignon
Post by map
Tell me what you think, if I should bugger off, post this somewhere
else, whatever. I await your replies!
The authors of scheme discovered the equivalence between closures and
objects fourty years ago.
http://schemers.org/
Indeed, however I was curious to know what one would think about a
programming language based on this.
Well, scheme kinds of embodies this principle, and I think highly of
scheme and lisp, so I guess your language would have a favorable
outlook.

On the other hand, it has a strange syntax, probably not homoiconic, and
it may lack the other good qualities of scheme and lisp; since it
doesn't seem to propose anything not provided by lisp for several
decades, it doesn't look interesting.

Hence my advice: study the work done in programming language design,
including the most advanced concepts (studying Common Lisp, scheme,
Haskell, Clojure), and also the failures, (such as perl, python, java,
amongst others), might help you propose something more interesting.


Finally, I'll say that programming language design is a highly
controversal domain, and you should be careful seeking inspiration from
actual science, and not from popularity. Most (if not all) of the
"popular" languages are the worst (and have always been, from FORTRAN
and COBOL to C++ and Java).
--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.
Gremnebulin
2011-04-24 11:54:29 UTC
Permalink
Post by Pascal J. Bourguignon
Post by map
Tell me what you think, if I should bugger off, post this somewhere
else, whatever. I await your replies!
The authors of scheme discovered the equivalence between closures and
objects fourty years ago.
http://schemers.org/
That's still contentious. A closure as such does not have mutable
state, or a complex interface. However, it can construct an object
with those features.
Gremnebulin
2011-04-23 19:47:06 UTC
Permalink
Post by map
I'm rather new to Usenet, so forgive me from barging on in here/
forgetting etiquette/etc.
Since this seems to be the place to do so, I'd decided to follow in
the
footsteps of the great and introduce the world to my programming
language
here.
Over the past two years or so in an effort to learn C I created an
interpreter for a programming language I also developed. The language
is
called FACT, or, Functions Are Classes Too. The basic concept behind
the
language is that classes/objects and functions/scopes can be combined
with
each other, thus creating a combination between the two famous PLT
paradigms (and I know I'm sounding rather pretentious at this point)
procedural and object-oriented programming. If you'd like to jump
right in
to the code, it's released here (I can't figure out how to post
sources on
Usenet):https://github.com/rookieMP/FACT
Moving on, here's the concept explained: Say one where to have a
function
f (). When we call it a new scope is created and by the time it
returns
three local variables are declared within its scope, x, y, and z. Now
lets
say this scope is called S. S contains three elements (as stated
earlier),
x, y and z. We can modify S by accessing these elements and changing
them,
we can even add elements to the scope and add other scopes as well.
But
how to we assign scopes? Let me also mention that each scope (very
much
similar to file systems) contains an "up" and "this" variable. The up
variable points to the next scope upward, and this (as you probably
know)
depends on if the language is lexically or dynamically scoped. The
this
variable points to the current scope. The "this" variable is very much
important for the creation of classes from functions. If a function
were
to return the "this" variable upon completion, it returns essentially
an
object. Methods can be defined by declaring functions withing
functions.
That's exactly how objects are constructed from functions in
javascript, down
to returning a "this" that is actually called "this" !

(Although I think that is more a case of Function Are Constructors
Too, than Functions Are Classes Too).
map
2011-04-25 05:13:16 UTC
Permalink
Post by Gremnebulin
Post by map
I'm rather new to Usenet, so forgive me from barging on in here/
forgetting etiquette/etc.
Since this seems to be the place to do so, I'd decided to follow in
the
footsteps of the great and introduce the world to my programming
language
here.
Over the past two years or so in an effort to learn C I created an
interpreter for a programming language I also developed. The language
is
called FACT, or, Functions Are Classes Too. The basic concept behind
the
language is that classes/objects and functions/scopes can be combined
with
each other, thus creating a combination between the two famous PLT
paradigms (and I know I'm sounding rather pretentious at this point)
procedural and object-oriented programming. If you'd like to jump
right in
to the code, it's released here (I can't figure out how to post
sources on
Usenet):https://github.com/rookieMP/FACT
Moving on, here's the concept explained: Say one where to have a
function
f (). When we call it a new scope is created and by the time it
returns
three local variables are declared within its scope, x, y, and z. Now
lets
say this scope is called S. S contains three elements (as stated
earlier),
x, y and z. We can modify S by accessing these elements and changing
them,
we can even add elements to the scope and add other scopes as well.
But
how to we assign scopes? Let me also mention that each scope (very
much
similar to file systems) contains an "up" and "this" variable. The up
variable points to the next scope upward, and this (as you probably
know)
depends on if the language is lexically or dynamically scoped. The
this
variable points to the current scope. The "this" variable is very much
important for the creation of classes from functions. If a function
were
to return the "this" variable upon completion, it returns essentially
an
object. Methods can be defined by declaring functions withing
functions.
That's exactly how objects are constructed from functions in
javascript, down
to returning a "this" that is actually called "this" !
(Although I think that is more a case of Function Are Constructors
Too, than Functions Are Classes Too).
Yes, the two languages are very similar. However, one difference is
the
mutability of scopes. Also, JavaScript excludes the "up" keyword,
which
is used to create inheritance, super/sub classes, etc.
Paul Rubin
2011-04-30 07:27:41 UTC
Permalink
This is inspired by Robert Harper's blog posts about Haskell vs. ML.
I'm interested in seeing idiomatic ML for an algorithm that expresses
itself pretty naturally in Haskell using lazy evaluation. It simply
checks if a number is prime through the "schoolboy" algorithm of trying
2 and then all odd candidate divisors until reaching sqrt(n):

isPrime :: Integral a => a -> Bool
isPrime n = null . take 1 $ [p | p <- candidates, n`mod`p == 0]
where
candidates = takeWhile (\k -> k*k <= n) (2:[3,5..])

This generates candidates 2,3,5,7,9,... and selects the ones (if any)
that evenly divide n, giving a lazy list. Then it takes the initial
sublist of up to 1 element (i.e. either 1 element or empty). If this
sublist is empty, the number is prime. "null" tests for empty by seeing
if the list has a first element or is nil. Therefore the function does
about what you would expect an imperative loop to do, running in
constant space and breaking out of the loop as soon as a divisor is
found.

Just for comparison (not trying to start an argument) I'm wondering what
the cleanest/prettiest way to do this in SML is, maybe using force/delay
or maybe not. I do agree with some of Harper's issues with Haskell and
have been wanting for a while to spend some time on SML.

Thanks.

Paul
Adrian Hey
2011-04-30 15:34:10 UTC
Permalink
Hello Paul,
Post by Paul Rubin
This is inspired by Robert Harper's blog posts about Haskell vs. ML.
I'm interested in seeing idiomatic ML for an algorithm that expresses
itself pretty naturally in Haskell using lazy evaluation. It simply
checks if a number is prime through the "schoolboy" algorithm of trying
isPrime :: Integral a => a -> Bool
isPrime n = null . take 1 $ [p | p<- candidates, n`mod`p == 0]
where
candidates = takeWhile (\k -> k*k<= n) (2:[3,5..])
This generates candidates 2,3,5,7,9,... and selects the ones (if any)
that evenly divide n, giving a lazy list. Then it takes the initial
sublist of up to 1 element (i.e. either 1 element or empty). If this
sublist is empty, the number is prime. "null" tests for empty by seeing
if the list has a first element or is nil. Therefore the function does
about what you would expect an imperative loop to do, running in
constant space and breaking out of the loop as soon as a divisor is
found.
I don't think there's any guarantee that this will run in constant
space in Haskell. In fact AFAIK it won't with GHC by default. I think
you need to inhibit full laziness to get constant space solution.
Otherwise by default (at least with -O) it will lift the constant
infinite list (2:[3,5..]) to top level so it will be shared by all
applications of isPrime.

See this ticket for another example and discussion of the problem..
http://hackage.haskell.org/trac/ghc/ticket/917

Clean OTOH has no such problems IIRC, so this isn't so much a laziness
problem in general, it's specific to Haskell. (Clean semantics are
specified directly in terms of graph reduction, so the compiler
shouldn't do anything to change graph sharing from what the programmer
specified. With Haskell you only get denotational sementics and graph
reduction is just an implementation technique. So the whole issue of
what compiler transformations are reasonable & _operationally_
beneficial is somewhat ambiguous with Haskell.)

As for an SML solution to this particular problem, I'm afraid I've
forgotten SML syntax so won't attempt it. But there is a straight
forward constant space tail recursive solution that could be used in
SML or even Haskell..

isPrime n = not (even n) && f 3
where f k = if (k*k > n) then True
else if (n `mod` k == 0)
then False
else f (k+2)

.. or something like that (untested code).

Regards
--
Adrian Hey
Torben Ægidius Mogensen
2011-05-03 08:05:08 UTC
Permalink
Post by Paul Rubin
This is inspired by Robert Harper's blog posts about Haskell vs. ML.
I'm interested in seeing idiomatic ML for an algorithm that expresses
itself pretty naturally in Haskell using lazy evaluation. It simply
checks if a number is prime through the "schoolboy" algorithm of trying
isPrime :: Integral a => a -> Bool
isPrime n = null . take 1 $ [p | p <- candidates, n`mod`p == 0]
where
candidates = takeWhile (\k -> k*k <= n) (2:[3,5..])
This generates candidates 2,3,5,7,9,... and selects the ones (if any)
that evenly divide n, giving a lazy list. Then it takes the initial
sublist of up to 1 element (i.e. either 1 element or empty). If this
sublist is empty, the number is prime. "null" tests for empty by seeing
if the list has a first element or is nil. Therefore the function does
about what you would expect an imperative loop to do, running in
constant space and breaking out of the loop as soon as a divisor is
found.
Just for comparison (not trying to start an argument) I'm wondering what
the cleanest/prettiest way to do this in SML is, maybe using force/delay
or maybe not. I do agree with some of Harper's issues with Haskell and
have been wanting for a while to spend some time on SML.
In SML, you probably wouldn't use a list of candidates but merge the
generation of candidates with the modulo tests, much like a deforested
version of the above would. Something like

fun isPrime n =
n mod 2 <> 0 andalso
let fun test k =
k*k>m orelse n mod k <> 0 andalso test (k+2)
in test 3 end

You can do it with streams, but for such a simple example you probably
would not.

Torben

Loading...