A Dylan Primer for Python Programmers

Note

If one column contains N/A, then that language has no corresponding direct way to express what is in the other column.

Literals

Python

Dylan

True
#t
False
#f
23
23
0b1011
#b1011
0o644
#o644
0x2A5F
#x2A5F
6.02e+23
6.02e+23 // double float
6.02s+23 // single float
6.02d+23 // double float

N/A

No individual characters other than integer character codes

'a'
'\n'
'Hello'
'Hello\n'
"Hello"
"Hello\n"
s = '''Hi, from
python'''


# No Rectangle rule
s = '''
    Hi, from
    Python
    '''
let s = """
Hi, from
Dylan
""";
// Rectangle rule support
let s = """
        Hi, from
        Dylan
        """;

N/A

Not real symbols but strings are interned

#"apple"
apple:

N/A

No symbols

#"two words"
(1, 'a', 'dog')

N/A

No tuples (see multiple values)

[5, 10, 15]
#[5, 10, 15]

Syntax

Note

In Dylan, any words after an end (e.g. end method) are optional but, if present, must match the corresponding “begin” word.

Python

Dylan

var = exp



VAR = exp # Convention
let var = exp;
var := exp;
define variable var = exp;
define variable var :: type = exp;
define constant var = exp;
f(x, y, z)
f(x, y, z)
1
2
3
begin 1; 2; 3; end
begin 1; 2; 3 end
lambda x, y, *z:
  print('hello')
  return f(x, y, z)
method (x, y, #rest z)
  format-out("hello");
  f(x, y, z)
end method
x, y = exp
let (x, y) = exp
x, y = (5, 6)
f(x, y)
let (x, y) = values(5, 6);
f(x, y)
def foo():
  def f(x):
    f-body

  def g(y, z):
    g-body

  body
define function foo ()
  local method f (x)
          f-body
        end,
        method g (y, z)
          g-body
        end;
  body
end;
if test:
  then1
  then2
else:
  else1
  else2
if (test)
  then1;
  then2;
else
  else1;
  else2;
end if
a and b and c
a & b & c
a or b or c
a | b | c
if test1:
  result1
elif test2:
  result2
else:
  result
case
  test1 => result1;
  test2 => result2;
  otherwise => result
end case
if exp in (1, 2):
  result1
elif exp in ('a', 'b'):
  result2
else:
  result
select (exp)
  1, 2 => result1;
  'a', 'b' => result2;
  otherwise => result
end select
c = comparison-func(exp)
if c == 'foo':
  result1
elif c == 'bar':
  result2
else:
  result
select (exp by comparison-func)
  "foo" => result1;
  "bar" => result2;
  otherwise => result
end select
var1 = init1
var2 = init2
while not test:
  body
  var1 = step1
  var2 = step2
return var1
for (var1 = init1 then step1,
     var2 = init2 then step2,
     until: test)
  body
finally var1
end for

Predefined functions

Boolean functions

Python

Dylan

not obj
~ obj
~obj
isinstance(obj, bool)
instance?(obj, <boolean>)

Equivalence predicates

Python

Dylan

x == y
x = y
x is y
x == y

Symbols

Python

Dylan

N/A

instance?(obj, <symbol>)

N/A

as(<string>, sym)
as(<symbol>, str)

Numerical operations

Python

Dylan

isinstance(obj,
  (int, float, complex))
instance?(obj, <number>)
isinstance(obj, complex)
instance?(obj, <complex>)
isinstance(obj,
  (int, float))
instance?(obj, <real>)
isinstance(obj, int) or
  (isinstance(obj, float) and
    obj == int(obj))
instance?(obj, <rational>)
isinstance(obj, int)
instance?(obj, <integer>)
integral?(num)
n1 == n2
n1 == n2
n1 < n2
n1 < n2
n1 > n2
n1 > n2
n1 <= n2
n1 <= n2
n1 >= n2
n1 >= n2
n == 0
0 == 0.0 # True
zero?(n)
0 == 0.0 // #f
n > 0
positive?(n)
n < 0
negative?(n)
i % 2 != 0
odd?(i)
i % 2 == 0
even?(i)
1 + 2 + 3
1 + 2 + 3
1 * 2 * 3
1 * 2 * 3
5 - 3
5 - 3
1 / 2 # 0.5
1 / 2           // error
1.0 / 2         // 0.5
truncate/(1, 2) // 0
ceiling/(1, 2)  // 1
floor/(1,2)     // 0
-x
- x
-x
2 ** 16
2 ^ 16
max(1, 2, 3)
max([1, 2, 3])
max(1, 2, 3)
apply(max, #(1, 2, 3))
5 % 2
remainder(5, 2)

Characters

Python

Dylan

isinstance(obj, str) and
  len(obj) == 1
instance?(obj, <character>)
char1 == char2
char1 == char2
char1 < char2
char1 < char2
char1 > char2
char1 > char2
char1 <= char2
char1 <= char2
char1 >= char2
char1 >= char2
ord(char)
as(<integer>, char)
chr(n)
as(<character>, n)
char.upper()
as-uppercase(char)
char.lower()
as-lowercase(char)

Strings

Python

Dylan

isinstance(obj, str)
instance?(obj, <string>)
'x' * k
make(<string>, size: k, fill: char)
"".join('a', 'b', 'c'])
as(<string>, #['a', 'b', 'c'])
len(str)
size(str)
str.size
str[k]
element(str, k)
str[k]
# Strings are immutable
element-setter(char, str, k)
str[k] := char
str1 == str2
str1 = str2
str1 < str2
str1 < str2
str[start:end]
copy-sequence(str, start: start, end: end)
str1 + str2
concatenate(str1, str2)
list(str)
as(<list>, str)
list(str)
as(<string>, chars)
copy(str)
shallow-copy(str)
copy-sequence(str)
# Strings are immutable
fill!(str, char)

Vectors

Python

Dylan

isinstance(obj, list)
instance?(obj, <vector>)
[fill] * k
make(<vector>, size: k, fill: fill)
[obj, ...]
vector(obj, ...)
len(vec)
size(vec)
vec.size
vec[k]
element(vec, k)
vec[k]
vec[k] = obj
element-setter(obj, vec, k)
vec[k] := obj
list(vec)
as(<list>, vec)
# Uses lists for both
list(list)
as(<vector>, list)
for i in range(len(vec)):
  vec[i] = obj
fill!(vec, obj)

Control Features

Python

Dylan

callable(obj)
instance?(obj, <function>)
proc(arg1, arg2, *args)
apply(proc, arg1, arg2, args)
map(proc, list1, list2, ...)
# returns iterator in
# Python 3
map(proc, list1, list2, ...)
map(proc, vec1, vec2, ...)
map(proc, vec1, vec2, ...)
map(proc, str1, str2)
map(proc, str1, str2)
for a,b in zip(list1, list2):
  proc(a, b)
do(proc, list1, list2)

Continuations

Python doesn’t have first-class continuations like Scheme’s call/cc, and Dylan’s block syntax is more like structured exception handling or generators.

Here are approximate equivalents:

Python

Dylan

def example():
  try:
    body()
  except Error as e:
    handle_error()
  finally:
    cleanup_stuff()
block (k)
  body
exception (e :: <error>)
  handle-error()
cleanup
  cleanup-stuff
end block

N/A

define function top ()
  block (exit-block)
    bar(exit-block);
    format-out("You won't see this.\n");
  end;
  format-out("You WILL see this.\n");
end;

define function bar (thunk)
  thunk()
end;

top();

Keyword arguments

Python

Dylan

def wrapper_fn (a, b, c, **keys):
  do_stuff(a, b, c)
return wrapped_fn(**keys)

def wrapped_fn (one = 1, two = 2, three = 3):
  return [one, two, three]
define method wrapper-fn (a, b, c, #rest keys)
  do-stuff(a, b, c);
  apply(wrapped-fn, keys)
end;

define method wrapped-fn
  (#key one = 1, two = 2, three = 3)
  list(one, two, three)
end;

Python collects any number of keyword arguments into a dictionary. In Dylan, #rest keys collects the remaining arguments, not into a dictionary, but into a vector (like a property list or plist): alternating symbol-value pairs.