Skip to content

Latest commit

 

History

History
225 lines (156 loc) · 3.4 KB

expressions.md

File metadata and controls

225 lines (156 loc) · 3.4 KB

Expressions

Literals

  • 1 evaluates to an instance of Int
  • 1.0 evaluates to an instance of Float
  • "foo" evaluates to an instance of String
  • true and false evaluates to an instance of Bool

Array literal

  • [1, 2] evaluates to an instance of Array<Int>
  • [1, "foo"] evaluates to an instance of Array<Object>

Self expression

Example

class A
  def foo
    self  #=> The type of `self` is `A` here
    self.bar
  end

  def bar
    puts "bar"
  end
end

In the toplevel, self evaluates to the toplevel self. The type of toplevel self is Object.

Variable declaration/assignment

There are two ways to declare a local variable.

  • let x = 1
  • var x = 1

Reassigning to x only allowed for the latter form.

  • let @a = 1
  • var @a = 1

Lambda expression

An instance of the classes Fn0, Fn1, ..., Fn9 is called a lambda. Lambdas can be created by lambda expression.

  • fn{ p 1 } evaluates to an instance of Fn0<Void>
  • fn(x: Int){ p x } evaluates to an instance of Fn1<Int, Void>

Invoking a function

f = fn{ p 1 }
f()

f must be an instance of Fn.

Method call

  • 1.abs
  • foo
  • foo()
  • foo(1, 2, 3)

Blocks

  • foo(1, 2, 3){|x: Int| p x}
  • foo(1, 2, 3) do |x: Int| p x end

These are mostly equal to

  • foo(1, 2, 3, fn(x: Int){ p x })

but some behaviors, break and return for example, are different between fn (a lambda made by lambda expression) and block (a lambda made by {} or do...end on a method call).

Logical operators

The type of these expressions are Bool.

  • !x
  • x and y
  • x or y

Conditional expression

If

Example

if foo
  puts "foo"
elsif bar
  puts "bar
else
  puts "otherwise"
end

x = if a then b else c end

The type of an if condition (foo, bar and a avobe) must be Bool.

else-less if, for example

if foo
  puts "foo"
end

is equivalent to

if foo
  puts "foo"
else
  Void
end

Type of an if expression

  1. Never if all branches have type Never. Otherwise:
  2. Void if a branch has type Void. Otherwise:
  3. If all the branches have either type Never or type A, A. Otherwise this if is invalid (compile-time error.)

If modifier

x if y is equivalent to

if x
  y
end

Unless

unless foo
  puts "otherwise"
end

is equivalent to

if !foo
  puts "otherwise"
end

Note: unless cannot take elsif or else clause.

Unless modifier

x unless y is equivalent to

if !x
  y
end

Conditional operator

a ? b : c is equivalent to

if a
  b
else
  c
end

Loop and jump expressions

While

var a = 1
while a < 10
  p a
  a += 1
end

Type of a while expressions is Void.

Break

  1. Find the nearest while/fn/block
  2. If the found one is while, escape from the while
  3. If the found one is fn, compile-time error
  4. If the found one is block, escape from the method that given the block
  5. If none found, compile-time error

Example

[1, 2, 3].each do |i: Int|
  p i
  break if i == 2  #=> escapes from `each`
end

Type of a break expressions is Never.

Return

  1. Find the nearest fn/method
  2. If the found one is fn, escape from the fn
  3. If the found one is method, escape from the method
  4. If none found, compile-time error

Type of a return expressions is Never.

(NOTE: non-local return is not yet implemented - see #242)