[Prev][Next][Index][Thread]

Re: A Dylan FAQ



Some more answers. 

On Tue, 10 Apr 2001 08:01:05 -0400 (EDT), Rob Myers <robmyers@mac.com> wrote:
>OK, here's some more, with what people already posted worked in.
>
>
> Why is this broken: #( fun1(), fun2(), fun3())?

You've run into a minor quirk of Dylan syntax. One of the restrictions
on literal list and vector notation is that they can only contain
other literals.  That is, this is legal Dylan:

  begin
    let y = #[1, 2, 3];
    f(y);
  end;

but this is not:

  begin
    let three = 3;
    let y = #[1, 2, three];
    f(y);
  end;

because the variable three is not a literal expression. To get the
effect you want, use the list() or vector() functions:

  begin
    let three = 3;
    let y = vector(1, 2, three);
    f(y);
  end;

> What's the difference between "Hello" and #"Hello" ?

In addition to strings, Dylan also has a data type called symbols.
"Hello" is a literal string, and #"Hello" is a literal symbol.

The difference between symbols and strings are these:

1. Two \= strings may return #f for \==, whereas for symbols \= and \== 
   are guaranteed to be the same. 

2. Symbols are case-insensitive -- #"foo" and #"FOO" are the same
   symbol.

3. Symbols are immutable, whereas strings can be changed. 

> What's the difference between #"Hello" and Hello: ?
> So why should I use the former for symbols and the latter for keywords?

Semantically, there's no difference -- both forms are literal syntax
for the symbol #"hello".

Culturally, there are strong norms for when different versions should
be used. When Dylan syntax needs a keyword, use the keyword ":"
syntax, and when using symbols as values, use the #"" syntax.

> How do I exit a (deep) loop like in C++ or Java?

Use the block form's exit-function:

  block(return)
    for (x in sequence1)
      for (y in sequence2)
        if (complicated-condition?(x, y))
          return(g(x,y))
        end if;
      end for;
    end for;
  end block;

> What names does Dylan define behind-the-scenes?

All of Dylan's builtin names are defined in the Dylan module. You can
find a list at:

  http://www.gwydiondylan.org/drm/drm_119.htm#HEADING119-1

> What are -getter and -setter methods?

Whenever you see an slot reference like 'foo.bar' in Dylan, you are
actually seeing a function call "bar(foo)". Every reference to an
object's instance variables is actually wrapped in a method call in
Dylan. This permits you to easily provide access to an object's data,
without committing yourself to keeping that data layout in the object.

This is different from C++ and Java, and similar to Eiffel.

Likewise, whenever you see an assignement to an slot like this:

  foo.bar := baz;

this is syntactic sugar for

  bar-setter(baz, foo);

Again, this lets you conveniently expose object data to clients
without commiting yourself to the data layout.


> How do I export a slot form a module?

To export the slot "foo" on an object, write a module definition
like this:

  define module an-example
    use Dylan;
  
    export foo;
  end module;

If the slot is mutable, add the foo-setter binding to the export
list:

  define module an-example
    use Dylan;

    export foo, foo-setter;
  end module;

You only need to add the slot to the export list if its generic
function was defined in that module, though. 

> What are first-class types and functions?

In a programming language, a value is called "first-class" if it can
be created at runtime, passed to functions as arguments, returned as
values from functions, and stored in data structures.

Almost all languages treat integers and floats as first-class, for
example, but few extend this to other language constructs like
functions and types. C, for example, has no data structure
representing the language's types, and new functions cannot be
generated at runtime.

Dylan permits you to manipulate functions and types as first class
values: you can create and pass around lists of functions and types.
This is useful (for example) in the collection protocol: the generic
function type-for-copy returns the type a copy of a collection should
be, which permits a single implementation of functions like map and
reduce to operate polymorphically on many different types of
collection.

(An example of a second-class value are macros. You can only create
them at the toplevel, and you can't store them in data structures, and
they can only be applied and exported from modules.)

> What is Syntactic Sugar?

Syntactic sugar is syntax added to a language that makes certain kinds
of expressions easier to write, but which doesn't really add any power
to the language.

For example, arithmetic expressions could easily be written in terms
of function calls -- 3 + 5 * 7 could be written add(3, multiply(5, 7)),
but for most people the first form is easier to read, so language
designers added it to their languages.

Careful use of syntatic sugar permits a programming language to
express key concepts clearly and without clutter. However, overuse and
abuse of sugar leads to highly unreadable programs. (APL and Perl are
famous for permitting programmers to write unreadable programs.)

Dylan permits programmers to add syntax to the language via its macro
system. 


Neel