Emmy
1 Definitions
define
2 Types
define-type
2.1 Special top-level type constructors.
Struct
Named  Options
3 Procedures
lambda
4 The Object Browser
browse
browse-stack-here
break-at
5 Other Syntax
:
->
...
λ
6 The Image Library
7 Internals
8.6

Emmy

 #lang emmy package: emmy

Emmy is a new student language for 111. Everything is subject to change, especially the documentation.

Report any problems with Emmy here. Good error messages are one of Emmy’s goals. If you see an unhelpful one, please report it. Questions, suggestions, and contributions are also welcome.

1 Definitions

syntax

(define name expr)

(define (name arg ...) etc ...)
The first form defines name as the result of expr. The second form converts directly to:

(define name
  (lambda (arg ...)
    etc ...))

2 Types

All user-defined types must be capitalized.

syntax

(define-type name t)

Defines name as type t, where t is a Typed Racket type or special top-level type constructor.

2.1 Special top-level type constructors.

Certain type constructors can only be used at the top level of a type definition.

syntax

(define-type Name (Struct [field : type]
                          ...))
Defines Name as a structure type. The following names are defined:
  • Name is defined as a type, corresponding to instances of the struct.

  • Name is also defined as a procedure that takes an argument for each field and returns a new instance of the struct.

  • Name? is defined as a predicate that returns #t given an instance of the struct and #f for any other value.

  • Name-field, for each field, a procedure that takes an instance of the struct and returns the value for the given field.

(define-type Vector2 (Struct
                      [x : Number]
                      [y : Number]))
 
(define (vector2-+ [a : Vector2] [b : Vector2]) -> Vector2
  "Adds two Vector2s"
  (Vector2 (+ (Vector2-x a)
              (Vector2-x b))
           (+ (Vector2-y a)
              (Vector2-y b))))
 
(define V1 (Vector2 1 2))
 
(vector2-+ V1
           (Vector2 3 4))

Struct instances display as <Name field=val ...>.

syntax

(define-type Name (NamedOptions opt ...))

Defines each opt as a singleton type, and Name as their union.

(define-type Image-Mode (NamedOptions Solid Outline))

3 Procedures

syntax

(lambda maybe-name (arg ...) -> return-type
  maybe-desc
  body ...+)
 
arg = [arg-name : type]
     
maybe-name = 
  | name-string
     
maybe-desc = 
  | desc-string
Creates a procedure. It accepts an argument for each arg (as long as it is correctly typed), and returns the value of the final expression in body, which must be of type return-type.

Procedures may be given names and descriptions, and will display as |{|name|;| desc|}|. Procedures at the top level of a define are named accordingly.

Single capital letters serve as ’type variables’ and can be used for generic procedures:

(define second
  (λ ([lst : (Listof A)]) -> A
    "Gets the second element of a homogeneous list"
    ; first/rest don’t exist yet
    (car (cdr lst))))

Note that this version of second requires all elements of the given list to be the same type. Replacing A with Any would remove this restriction.

4 The Object Browser

The object browser will be launched whenever a runtime(ish) error occurs, examining the stack at the time of the error.

procedure

(browse v)  Void

  v : Any
Opens v in the object browser. This doesn’t pause the program, so be careful calling it in a loop!

procedure

(browse-stack-here)  Void

Shows the current call stack in the object browser. Click "Continue program" to unpause.

procedure

(break-at v)  Void

  v : Any
Not implemented

Opens v and the current call stack in the object browser. Click "Continue program" to unpause.

5 Other Syntax

syntax

[n : t]

Denotes that n is defined to have type t.

syntax

-> t

Denotes that a procedure returns a value of type t.

syntax

f ...

Denotes that f may repeat any number of times. Used only in documentation.

syntax

λ

Alias of lambda.

6 The Image Library

It doesn’t exist. (But look at test/images.rkt for what it could look like.)

7 Internals

Emmy has some features for autograding and library development. In the future, these may either be solidified into the main language or moved to a sub-language.

- proc*-typestring gets the typestring (as seen in Dagger) of a procedure.

- proc*-arg-types and proc*-return-type get type info as a symbol or nested list of symbols. Currently, infix vs prefix ->s will keep their given shape, which needs to be fixed in order to be suitable for autograding.

- Explicit type variables can be given with #:forall (V ...), before the name/args in shortcut notation or anonymous lambdas. If provided, automatic type variables will not be discovered.

- Each instance of a struct carries information about its type with s-name, s-fields, and s-types.