Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-

Algol 68

Name: Anonymous 2013-03-12 23:02

Algol 68 looks like a modern language (except for the uppercase keywords) even though it's older than C. It had real garbage collection and user-defined operators.
This is a program that defines a tree structure and some operations on it:
MODE LEAF = INT;
MODE TREE = STRUCT(REF TREE l, LEAF c, REF TREE r);
MODE ACTION = STRUCT(PROC VOID in, PROC(REF LEAF)VOID leaf, PROC VOID out);
BOOL left = TRUE, right = FALSE;
OP & = (TREE t)REF TREE: HEAP TREE := t;
OP & = (LEAF l)REF TREE: HEAP TREE := (NIL, l, NIL);
OP ^ = (PROC(REF LEAF)VOID p)ACTION: (VOID: EMPTY, p, VOID: EMPTY);
PRIO -> = 1, OP -> = (REF TREE src, REF REF TREE dest)REF REF TREE: dest := src;
OP LEFT = (REF TREE t)REF REF TREE: l OF t;
OP RIGHT = (REF TREE t)REF REF TREE: r OF t;
PROC walk = (REF TREE t, ACTION action)VOID: (t :/=: NIL |
    in OF action;
    walk(l OF t, action);
    (leaf OF action)(c OF t);
    walk(r OF t, action);
    out OF action);
PROC follow = (REF TREE t, []BOOL path)REF REF TREE: (
    PROC loop = (REF REF TREE n, []BOOL path)REF REF TREE:
        IF UPB path < 1 THEN
            n
        ELSE
            loop(IF path[1] THEN l OF n ELSE r OF n FI, path[2:@1])
        FI;
    loop(LOC REF TREE := t, path[@1]));
PROC(REF TREE)VOID display = walk(, (VOID: print("("), (REF LEAF l)VOID: printf(($g(0)$, l)), VOID: print(")")));
PRIO JOIN = 5, OP JOIN = (LEAF init, REF TREE t)LEAF: (
    LEAF coll := init;
    walk(t, ^((REF LEAF l)VOID: coll +:= l));
    coll);

TREE tree := (&TREE(&7, 1, &TREE(&-3, -5, &-4)), 2, &TREE(&8, 3, NIL));
display(tree); print(new line);
print(0 JOIN tree);
&TREE(&5, 6, &7) -> LEFT LEFT tree;
display(RIGHT tree); print(new line);
display(tree); print(new line);
display(follow(tree, (left, right, right)))

This is a similar program in ML for comparison:
datatype 'a tree = NIL | TREE of 'a tree * 'a * 'a tree
type 'a action = (unit -> unit) * ('a -> unit) * (unit -> unit)
fun LEFT (TREE(l, _, _)) = l
  | LEFT NIL = NIL
fun RIGHT (TREE(_, _, r)) = r
  | RIGHT NIL = NIL
fun & l = TREE(NIL, l, NIL)
fun A l = ((fn() => ()), l, (fn() => ()))
fun walk ((TREE(l, c, r)), act as (in', leaf, out)) = (
         in'();
         walk(l, act);
         leaf(c);
         walk(r, act);
         out()
    )
  | walk (NIL, _) = ()
fun follow ((TREE(l, c, r)), (dir :: xs)) = follow(if dir then l else r, xs)
  | follow (t, nil) = t
  | follow (NIL, _) = NIL
fun display conv t = walk(t, (fn() => print("("), fn(l) => print(conv l), fn() => print(")")))
fun JOIN (init, t) = let val coll = ref init in
         walk(t, A(fn(l) => coll := !coll + l));
         !coll
    end
infix JOIN
val tree = TREE(TREE(&7, 1, TREE(& ~3, ~5, & ~4)), 2, TREE(&8, 3, NIL))
val _ = (print o Int.toString)(0 JOIN tree)
val _ = display Int.toString (tree)

Name: Anonymous 2013-03-12 23:44

Gonna need the Symta version for comparison.

Name: Anonymous 2013-03-13 1:14

CORRECTION: Modern languages have not evolved beyond Algol-68.

Get to work you slackers.

Name: Anonymous 2013-03-13 7:20

>>1
Algol also had call-by-name, which only Haskell reintroduced.

Modern languages have not evolved beyond Algol-68.
But they got classes and design patterns!

Name: Anonymous 2013-03-13 10:14

Algol68 the academic PL/I

Name: Anonymous 2013-03-13 17:44

You know, I always wondered, what caused the industry to change from Algol to C, then to C++, SS, PPP, JJ, RR, .... Lisp is the only merit after Algol68. Was it really the Unix OS? Or corporate interest to force unix to every machine *ahem IBM*?

I want to know your opinion /prog/.

Makes me wonder, was there a competitive OS like Unix in AlGOL?

Name: Anonymous 2013-03-13 20:27

that language looks disgusting

Name: Anonymous 2013-03-13 22:42

>>2
Symta version would be along the lines: tree L C R = (left = L | right = R)

because Symta uses closures in place of objects and pattern-matching to select multi-methods inside of them.

Name: Anonymous 2013-03-13 22:44

>>8
And inheritance implemented as a simple fallthrough case, which calls parent.

Name: Anonymous 2013-03-14 0:22

>>6
This is well-known. C won out because:

 - I/O libraries were standard (unlike Algol, where earlier dialects couldn't agree on a syntax for printing and getting input)
 - Assembly programmers trained in the early 60s who didn't believe a compiled language could ever be efficient were given a form of structured assembly that had minimal overhead.
 - It was absurdly portable (unlike said assembly).
 - It was small (unlike PL/I, which IBM and MIT wanted to become standard).
 - It was terse (LOLBOL).
 - It had good support for block structures (Fortran didn't back then).

But to be honest, C won out largely because of Unix. The only OS remotely similar to Unix at the time was Multics, and that was a very expensive beast written in PL/I (and just enough assembly to keep it from being portable.) Unix, on the other hand, was cheap, minimalist, and easily ported to other architectures. It brought C with it, and not many other OSes ever had a C compiler written for them.

(Windows and DOS don't count in this—MS was internally a Unix shop in the early 80s; their distro was named Xenix, which eventually became SCO Unix.)

There were elaborate operating systems written in Pascal-like languages, such as LILITH (written in Modula-2), but these were in competition with Xerox (Smalltalk) and Symbolics/LSI (Lisp). By that time, Algol was already forgotten behind languages like Lisp, Prolog, and Fortran; theorists preferred functional and logical programming, and scientists needed code that was easy to support on commodity hardware. These were the two major markets for Algol, and without them, it had nothing to fall back on.

Algol still gets a lot of mileage in PLT, though. Standard pseudocode syntax is based on Algol (usually with Pascal influence), and standard semantics textbooks still explore Algol's structure.

Name: Anonymous 2013-03-14 1:23

>>10
Thanks for writing that. I had my suspicions on the I/O and Unix. The only 2 I found close was Atlas and M8. But you are correct, they were not as portable.

Name: Anonymous 2013-03-14 21:00

>>4
Another thing Algol had in common with Haskell was the ability to use presentational characters. It was also expression-oriented like modern functional languages.
int initial foot width = 5;
mode foot = struct(
   string name,
   sema width,
   bits toe ¢ packed vector of BOOL ¢
);
 
foot left foot:= foot("Left", level initial foot width, 2r11111),
     right foot:= foot("Right", level initial foot width, 2r11111);
 
¢ 10 round clip in a 1968 Colt Python .357 Magnum ¢
sema rounds = level 10;
 
¢ the Magnum needs more barrels to take full advantage of parallelism ¢
sema acquire target = level 1;
 
prio ∧:= = 1;
op ∧:= = (ref bits lhs, bits rhs)ref bits: lhs := lhs ∧ rhs;
 
proc shoot = (ref foot foot)void: (
  ↓acquire target;
  ↓rounds;
  print("BANG! ");
  ↓width → foot;
  toe → foot ∧:= ¬(bin 1 shl level width → foot);
  printf(($g": Ouch!! - "5(g)l$, name → foot, []bool(toe → foot)[bits width - initial foot width + 1:]));
  ↑acquire target
);
 
¢ do shooting in parallel to cater for someone hoping to stand on just one foot ¢
par (
  for toe to initial foot width do
    shoot(left foot)
  od, ¢ <= a comma is required ¢
  for toe to initial foot width do
    shoot(right foot)
  od
)

Name: Anonymous 2013-03-14 22:14

too small for droid sans mono :(

Name: Anonymous 2013-03-14 22:31

>>13
Use DejaVu Sans Mono, ``faggot''.

Name: Anonymous 2013-03-14 23:37

Déjà-vu Sans Mononucléose

Name: Anonymous 2013-03-15 0:58

This is an alternate representation of the program in >>1.
mode Leaf = int;
mode Tree = struct(ref Tree l, Leaf c, ref Tree r);
mode Action = struct(proc void inf, proc(ref Leaf)void leaf, proc void outf);
bool left = true, right = false;
op & = (Tree t)ref Tree: heap Tree := t;
op & = (Leaf l)ref Tree: heap Tree := (○, l, ○);
op ^ = (proc(ref Leaf)void p)Action: (void: (), p, void: ());
prio -> = 1, op -> = (ref Tree src, ref ref Tree dest)ref ref Tree: dest := src;
proc walk = (ref Tree t, Action action)void: (t :≠: ○ |
    inf→action;
    walk(l→t, action);
    (leaf→action)(c→t);
    walk(r→t, action);
    outf→action);
proc follow = (ref Tree t, []bool path)ref ref Tree: (
    proc loop = (ref ref Tree n, []bool path)ref ref Tree:
        (⌈path < 1 | n | loop((path[1] | l→n | r→n), path[2:@1]));
    loop(loc ref Tree := t, path[@1]));
proc(ref Tree)void display = walk(, (void: print("("), (ref Leaf l)void: printf(($g(0)$, l)), void: print(")")));
prio Join = 5, op Join = (Leaf init, ref Tree t)Leaf: (
    Leaf coll := init;
    walk(t, ^((ref Leaf l)void: coll +:= l));
    coll);

Tree tree := (&Tree(&7, 1, &Tree(&-3, -5, &-4)), 2, &Tree(&8, 3, ○));
display(tree); print(new line);
print(0 Join tree);
&Tree(&5, 6, &7) -> l→l→tree;
display(r→tree); print(new line);
display(tree); print(new line);
display(follow(tree, (left, right, right)))

Name: Anonymous 2013-03-15 1:48

>>16
Y○L○!

Name: Anonymous 2013-03-15 11:57

Algol 68's the first language to have a sound type system with no loopholes. There's no way to unsafely coerce types.

Name: Anonymous 2013-03-15 11:59

>>18
U MENA HASKAL

Name: Anonymous 2013-03-15 17:50

>>19
Prelude> unsafeCoerce True :: Maybe Int
Just Segmentation fault (core dumped)

Name: Anonymous 2013-03-17 0:00

You can download Algol 68 interpreters/compilers here.
http://algol68.sourceforge.net/

Name: Anonymous 2013-03-17 5:28

I translated the Cont monad from Haskell into Algol 68.
http://en.wikibooks.org/wiki/Haskell/Continuation_passing_style
PROGRAM monad CONTEXT VOID USE standard
BEGIN
PRIO >> = 1, >>= = 1;
MODE A = INT, R = INT;
MODE CONT = STRUCT(PROC(PROC(A)R)R cont);
MODE KCONT = PROC(PROC(A)CONT)CONT, KACT = PROC(A)CONT, KFUN = PROC(A)R, KTYPE = PROC(PROC(A)R)R;
PROC cont = (KTYPE k)CONT: (CONT m; cont OF m := k; m);
PROC run cont = (CONT c)KTYPE: cont OF c;

OP RETURN = (A n)CONT: cont((KFUN k)R: k(n));
OP >>= = (CONT m, KACT f)CONT: cont((KFUN k)R: run cont(m)((A a)R: run cont(f(a))(k)));
OP >> = (CONT m, n)CONT: m >>= ((A a)CONT: n);
PROC call cc = (KCONT f)CONT: cont((KFUN k)R: run cont(f((A a)CONT: cont((KFUN _)R: k(a))))(k));
#
return n = Cont (\k -> k n)
m >>= f  = Cont (\k -> runCont m (\a -> runCont (f a) k))
callCC f = Cont $ \k -> runCont (f (\a -> Cont $ \_ -> k a)) k
#
PROC print a = (A a)R: (print(a); a);
PROC square c = (A x)CONT: RETURN (x ^ 2);
PROC add three c = (A x)CONT: RETURN (x + 3);
CONT bar = call cc((KACT k)CONT: (A n = 5; k(n) >> RETURN 25));

run cont(bar)(print a);
print(new line);
run cont(square c(4) >>= add three c)(print a)
END
FINISH

Name: Anonymous 2013-03-17 6:15

>>22
Quite amazing. I'll comment further once I understand it.

Name: Anonymous 2013-03-17 15:18

>>22

You're moms a cont!

Name: Anonymous 2013-03-17 23:26

Algol 68RS had a composable parametric module system like OCaml and SML.
PROGRAM (user) both
COMPOSE package1(userprog = package2(userprog = HERE user))
FINISH


PROGRAM (hole) p
COMPOSE x(x1 = a,
          x2 = b(b1 = HERE hole,
                 b2 = d,
                 b3 = e))
FINISH

Name: Anonymous 2013-03-18 19:04

FORTRAN

Name: Anonymous 2014-02-16 15:36

Bumping intensifies

Name: Anonymous 2014-02-16 16:04

Bump.

Name: Anonymous 2014-02-16 18:38

My favorite thing about of Algol 68 is the cascading coercions. If you have an array of structures, you can select a field from the whole array to get an array of fields. If the array is reference type, the array of fields is also mutable. If you have a reference to an array, you can select an element or slice to get a reference to that element or slice. If you have a reference to a struct, you can select a field to get a reference to the field.

They should have extended the coercions to the parameters and results of procedures, too. Several languages including Scala and Typed Racket do this. Since int is coercible to real, you should be able to use a procedure expecting a real anywhere you can use a procedure expecting an int and a procedure returning an int anywhere you can use a procedure returning a real. You should be able to select a field from a procedure returning a struct and get a procedure returning the value of that field.

Typed Racket's type system is like an improved version of Algol 68. In both languages, unions flatten and commute. Both have equi-recursive types. Both use single-field structs as the equivalent of Haskell's newtypes.

[1000]struct(real x, y, z) vec,
ref[]real rx = x of vec,
[]real x = x of vec

This gives you two arrays: rx is an array of references to the "x" field of each element and x is an array of the values the "x" fields had at the time the declaration was evaluated.

Or in pseudo-C++:
struct { float x, y, z } vec[1000];
float (&x)[] = vec.x;
float x[] = vec.x; // makes a copy

Name: Anonymous 2014-02-17 19:59

Algol was invented in China back in the 1960s.

They call it Algol because it is a good language for programming algolithms.

Don't change these.
Name: Email:
Entire Thread Thread List