Category: BYU

  • The Murder Ballad of Bishop Henri / Piispa Henrikin Surmavirsi

    The Murder Ballad of Bishop Henri / Piispa Henrikin Surmavirsi

    The Murder of Henri the Elder Project

    Introduction

    The Murder Ballad of Bishop Henri details the supposed start of Christianity in Finland. The origin of the story has its roots in the twelfth century. The actual ballad appears in the Kanteletar, a collection of Finnish poems and ballads compiled by Elias Lönnrot. It was originally published in 1840 under the name “Kanteletar taikka Suomen Kansan Wanhoja Lauluja ja Wirsiä” (Kanteletar, or Old Songs and Hymns of the Finnish People). The poems and verses that Elias Lönnrot gathered, played an important role in giving definition to the Finnish national identity which later led to Finland becoming an independent state.

    A depiction of Bishop Henri (Missale Aboense, the first book ever printed for Finland for usage in Mass)
    A depiction of Bishop Henri (Missale Aboense, the first book ever printed for Finland for usage in Mass)

    Summary

    The story begins with two brothers, King Eric of Sweden and Bishop Henri of Häme. Henri suggests to King Eric that they go Christianize the pagan lands of Finland. As Henri is traveling through Finland he becomes hungry and goes to the home of Lalli. Lalli is not there, but his wife, Kerttu, is. Henri takes what he needs from the home and leaves money behind. When Lalli returns home, Kerttu tells him that some people came and stole from them. Enraged, Lalli goes out to kill Bishop Henri.

    A shepherd and a slave both tell him on the way that his wife lied and he should not kill the Bishop. He ignores them though and eventually catches up to Bishop Henri. Before he dies, Bishop Henri tells his companions, that if he die, to gather his bones in the sled and let the ox take it wherever. Where the Ox eventually tires, there they are to build a church.

    After Lalli kills Bishop Henri, he takes his hat and ring. Upon returning home, the shepherd remarks on Lalli’s new ring and hat disapprovingly. Shamefully, Lalli removes the hat and ring. In doing so, he loses tufts of his hair and the ring strips the skin from off his finger. In this way, he receives a punishment from on high for murdering a holy man.

    The Moment of Attack, Lalli (left) Bishop Henri (right)
    The Moment of Attack, Lalli (left) Bishop Henri (right)

    The Ballad

    English

    Once there grew two children,
    one grew up in cabbage land,
    the other was raised in Sweden.
    The one from cabbage land,
    he was Henrik of Häme.
    The one raised in Sweden,
    he became King Eric.

    Henrik of Häme said
    to his brother Eric:
    “Let us go and baptize lands,
    lands that are yet unbaptized,
    places without priests!”

    King Eric said
    to his brother Henrik:
    “But the lakes are not yet frozen,
    the winding river is still flowing.”

    Henrik of Häme said
    to his brother Eric:
    “I will circle Kiulo Lake,
    around the winding river.”

    He harnessed his horses,
    placed bridles on them,
    set the carriages in place,
    attached the sled runners,
    fitted the wide shoes on,
    and the smaller sled planks.
    He soon set off driving,
    traveled the path, journeyed on,
    two spring days,
    and two nights in a row.

    King Eric said
    to his brother Henrik:
    “Hunger comes upon us,
    and there is neither food nor drink,
    nothing to bite or chew.”

    “There is Lalli across the bay,
    a good place atop the cape
    There we will eat and drink
    there we find food”

    Upon arriving there,
    Kerttu, the wicked mistress,
    spoke with a vile mouth,
    spouted unkind words.

    Then Henrik of Häme
    took hay for the horses,
    threw coins in its stead,
    took bread from the oven’s top,
    threw coins in its stead,
    took beer from the cellar,
    and left money in return.
    There they ate, there they drank,
    there they found sustenance;
    then they left to journey onward.

    Lalli returned home. –
    But Lalli’s wicked wife
    spoke with her vile mouth,
    spouted unkind words:
    “People came here,
    ate here, drank here,
    found sustenance here,
    took hay for the horses,
    threw coins in its stead,
    ate bread from the oven’s top,
    threw coins in its stead,
    drank beer from the cellar,
    left sand in its stead.”

    The shepherd on the hill said:
    “You surely have lied;
    do not believe her!”

    Lalli, the ill-natured one,
    a man of wicked lineage,
    took his swift horse,
    and his long spear,
    and chased after the lords.

    The loyal slave said,
    the faithful worker spoke:
    “There’s a rumble behind us;
    shall I drive the horse faster?”

    Henrik of Häme said:
    “If there is a rumble behind us,
    do not drive the horse faster;
    just keep the pace steady.”

    “What if they catch us
    or even kill us?”

    “Go behind a rock,
    listen from behind the rock.
    If I am caught
    or killed as well,
    gather my bones from the snow,
    place them in an ox’s sled,
    let the ox pull them to Finland.
    Wherever the ox tires,
    there a church shall be built,
    a chapel constructed,
    where the priest will preach,
    for all the people to hear.”

    The wicked one returned home.
    The shepherd on the hill said:
    “Where did Lalli get that hat,
    the evil man with a fine cap,
    the bishop’s mitre for a rogue?”

    So the man, in his sorrow,
    reached for the hat on his head:
    his hair fell in tufts.
    He removed ring from his finger:
    his flesh slipped away.

    Thus this ill-natured man,
    the wretched slayer of the bishop,
    received his punishment from on high,
    paid the price to the ruler of the world.

    Finnish

    Kasvoi ennen kaksi lasta,
    toinen kasvoi kaalimaassa,
    toinen Ruotsissa yleni.
    Se kuin kasvoi kaalimaassa,
    se Hämeen Heinrikki,
    se kuin Ruotsissa yleni,
    se on Eirikki kuningas.

    Sanoi Hämeen Heinrikki
    Eirikille veljellensä:
    ”Läkkäs maita ristimähan,
    mailla ristimättömillä,
    paikoilla papittomilla!”

    Sanoi Eirikki kuningas
    Heinrikille veljellensä:
    ”Ent on järvet jäätämättä,
    sulana joki kovera.”

    Sanoi Hämeen Heinrikki
    Eirikille veljellensä:
    ”Kyllä kierrän Kiulon järven,
    ympäri joki koveran.”

    Pani varsat valjahisin,
    suvikunnat suitsi suuhun,
    pani korjat kohallensa,
    saatti lastat sarjallensa,
    anturoillensa avarat,
    perällensä pienet kirjat.
    Niin kohta ajohon lähti,
    ajoi tietä, matkaeli,
    kaksi päiveä keväistä,
    kaksi yötä järjestänsä.

    Sanoi Eirikki kuningas
    Heinrikille veljellensä:
    ”Jo tässä tulevi nälkä
    eikä syöä eikä juoa
    eikä purtua pietä.”

    ”On Lalli lahen takana,
    hyvä neuvo niemen päässä,
    siinä syömmä, siinä juomma,
    siinä purtua piämmä.”

    Sitte sinne saatuansa
    Kerttu, kelvoton emäntä,
    suitsi suuta kunnotonta,
    keitti kieltä kelvotonta.

    Sitte Hämeen Heinrikki
    otti heiniä hevosen,
    heitti penningit sijalle,
    otti leivän uunin päältä,
    heitti penningit sijalle,
    otti olutta kellarista,
    vieritti rahat sijalle.
    Siinä söivät, siinä joivat,
    siinä purtua pitivät;
    sitte lähtivät ajohon.

    Tuli Lalli kotiansa. –
    Tuo Lallin paha emäntä
    suitsi suuta kunnotonta,
    keitti kieltä kelvotonta:
    ”Jo tässä kävi ihmisiä,
    täss’ on syöty, täss’ on juotu,
    tässä purtua pietty,
    viety heiniä hevosen,
    heitty hietoia sijahan,
    syöty leivät uunin päältä,
    heitty hietoja sijahan,
    juotu oluet kellarista,
    saatu santoa sijahan.”

    Lausui paimen patsahalta:
    ”Jo vainen valehtelitki,
    elä vainen uskokahan!”

    Lalli se pahatapainen
    sekä mies pahasukuinen,
    otti Lalli laukkarinsa,
    piru pitkän keihä’änsä,
    ajoi herroja taka’an.

    Sanoi orja uskollinen,
    lausui parka palvelija:
    ”Jo kuuluu kumu takana,
    ajanko tätä hevoista?”

    Sanoi Hämeen Heinrikki:
    ”Jos kuuluu kumu takana,
    elä aja tätä hevoista,
    karkottele konkaria.”

    ”Entä jos tavoitetahan
    taikkapa tapetahanki?”

    ”Käy sinä kiven ta’aksi,
    kuultele kiven takana,
    jos mua tavoitetahan
    taikka myös tapetahanki.
    Poimi mun luuni lumesta,
    ne pane härän rekehen
    härän Suomehen veteä.
    Kussa härkä uupunevi,
    siihen kirkko tehtäköhön,
    kappeli rakettakohon,
    papin saarnoja sanella,
    kansan kaiken kuultavaksi.”

    Palasi paha kotia,
    lausui paimen patsahalta:
    ”Kusta Lalli lakin saanut,
    mies paha hyvän hytyrän,
    pispan hiipan hirtehinen?”

    Niinpä mies murehissansa
    lakin päästänsä tavoitti:
    hivukset himahtelivat.
    Veti sormuksen sormesta:
    lihat ne liukahtelivat.

    Niin tämän pahantapaisen
    pispan raukan raatelijan
    tuli kosto korkialta,
    makso mailman valtialta.

    Impact

    Bishop Henri has gone on to become the Patron Saint of Finland and an enduring symbol of the Christianization of Finland. Lalli, despite his negative portrayal in the story, has also become a recognized symbol of Finnish resistance to foreign influence. Dozens of offshoot stories and legends surrounding the bishop and Lalli have popped up throughout the last centuries.

  • Guide to the Scheme Interpreter Project (BYU CS 111) Part 3

    Guide to the Scheme Interpreter Project (BYU CS 111) Part 3

    Part 1 Part 2

    We are finally to the last part of building our interpreter for Scheme in Python. In Part 3 we will implement our special form functions so that we can interpret And/Or, Conditionals, and the Let form in Scheme.

    Problem 12: And & Or

    Problem 12 deals with the And and Or form. We will be implementing two functions in scheme_forms.py: do_and_form() and do_or_form(). The purpose of these functions are to determine if an expression should evaluate to true or false based off of and/or logic or if it should return a value.

    Both functions will intake expressions, which will be a scheme list of individual expressions all represented in Pair objects. Understand that each sub-part of expressions is an expression in scheme being compared to the others by either ‘and‘ or ‘or‘.

    Scheme

    (and 1 5)

    Python

    expressions = Pair(1, Pair(5, nil))

    In scheme, ‘and‘ by itself evaluates to true, so it is truthy. In contrast, ‘or‘ by itself evaluates to false. We want to make the two functions recursive so that they go through each sub-part of expressions and either returns the value (or true/false if appropriate) or goes on to the next value in the expression.

    Check a value’s truthiness using the provided functions: is_scheme_true() and is_scheme_false().

    For do_and_form(), if you evaluate any of the expressions and it is a false value, return that value. Else, put the next expression into do_and_form() and recurse on until you get to the end or you get to a false value.

    For do_or_form(), if you evaluate any of the expressions and they are truthy, return that value. Else, put the next expression into do_or_form() and recurse on until you get to the end or you get to a true value.

    If you go through the entire scheme list of expressions and your function gets to the last element in the scheme list, return the value of that last part.

    Hint: What ‘and’ & ‘or’ look like alone

    Hint: Evaluating Expressions to Get the Value

    For more help

    Problem 13: Cond Form

    First of all, lets review the structure of the cond form.

    (cond (<predicate 1> <consequent expression>)
          (<predicate 2> <consequent expression>)
          (<else> <consequent expression>))

    Each conditional expression will have 1 or more predicates and in many cases will end with an else statement, but not always. We need to implement do_cond_form() such that it takes in expressions and goes through each predicate, testing if it is true. If it is true, it will return the value of the consequent expression. If not it will check the next predicate and do the same thing until we run out of predicates or hit an else statement. If there are no more predicates and no else statement, the function will simply not return anything (None).

    The function’s argument expressions will look something like so:

    Scheme

    (cond ((> 2 3) 5)

    (else 8))

    Python

    expressions = Pair(Pair(Pair(‘>’, Pair(2, Pair(3, nil))), Pair(5, nil)), Pair(Pair(‘else’, Pair(8, nil)), nil))

    We are provided some starter code for do_cond_form():

    Starter Code w/ Added Comments

    The while loop will run until we hit the end of the list of clauses, meaning expressions.rest will eventually be nil. In the indicated spot, we need to check if the clause has a consequent expression. If it does, we need to evaluate that expression and return it.

    Else, check if test is something other than true. If it is something else, that means test (which is an evaluation of the predicate) is just a value like (12), not an expression like (< 1 5) or (else). In that case we simply need to return the evaluation of the predicate.

    Lastly, if we get through all of these tests without returning anything, then it could mean two things. Either there was no predicates that were true and there was an else statement, but it did not have a consequent expression. Or it could mean that there was a true predicate without a consequent expression. In these case simply return true.

    For more help

    Problem 14: Let Form

    The let form allows us to bind variables locally. This means that when we use let, it creates a new frame in which these variables are defined. Consider the following example from the CS 111 instructions and the added environment diagram.

    scm> (define x 5)
    x
    scm> (define y 'bye)
    y
    scm> (let ((x 42)
    ...>     (y (* x 10)))
    ...> (list x y))
    (42 50)
    scm> (list x y))
    (5 bye)
    Global Frame 
    x      5
    y      bye
    Frame f1
    y      50
    x      42

    When the let expression is finished, the frame (f1) is closed and the variables defined by let disappear from the scope of the program. For more information on how let works, consult this page from the University of Texas on the let form. The last three paragraphs are particularly useful. Also refer to the CS 111 specs for let.

    To get the let form working in our scheme interpreter, we need to implement the make_let_form() in scheme_forms.py. make_let_frame() will return the new environment with the local variables defined. It takes in two arguments: bindings and env. bindings is a scheme list of variable names and values.

    Scheme

    scm> (let ((x 5))

    …> (+ x 3))

    Python

    bindings = Pair(Pair(‘x’, Pair(5, nil)), nil)

    You are going to need to figure out how you want to iterate through bindings to get each variable name and each value to which it is bound. Hint, you can use a while loop similar to the one in Problem 13.

    Check each part of bindings using validate_form() to insure they are the correct format. If the current part of bindings you are checking is the correct format, take the variable name from it and add it to the pre-defined variable names which is a scheme list.

    Then use validate_formals() on names to make sure it is still a legitimate format for a scheme list of names.

    Next, to get the value, use scheme_eval() to evaluate the part of bindings that is the value. Add that value to the pre-defined variable values which is also a scheme list.

    At the end of it all, your function should return a new environment with the new variables and values.

    Hint: validate_form()

    Hint: Adding to a Scheme List

    Hint: Where is the variable name in bindings?

    For more help

    </end>

    Hopefully this was a sufficient help. Please submit any corrections or questions in the comments below. I will try my best to answer and update the article accordingly.

  • Guide to the Scheme Interpreter Project (BYU CS 111) Part 2

    Guide to the Scheme Interpreter Project (BYU CS 111) Part 2

    Part 1 if you missed it

    In part 2 we will be implementing the code for procedures. By the end of this, you will be able to interpret user-defined functions, lambda functions, and something special called “Mu-procedures” that you will soon learn to dislike. This part will be handling problems 6-11. Good luck.

    In Scheme, we have the ‘begin’ special form. This lets us evaluate through a series of expressions in scheme and return only the value of the last expression.

    Excerpt from Berkeley CS61A Documentation

    It is useful because it allows for side effects from the first expressions to take place while returning only the evaluated value of the last expression in the series. For examples, see the examples in the CS 111 instructions and for even more understanding, read the short documentation for MIT/GNU’s implementation of scheme. Note from the documentation, that writing begin is often pointless because many special forms already apply it implicitly.

    What you need to do, is implement the eval_all() function in scheme_eval_apply.py. Eval_all() takes in two arguments: expressions and env.

    Scheme

    (1 2 3)

    Python

    expressions = Pair(1, Pair(2, Pair(3, nil)))

    You should go through expressions recursively, evaluating each one using scheme_eval(). When you get to the last expression, evaluate it like the others, but also return its value.

    For more help

    Problem 7: Lambda Procedures

    We need to implement the do_lambda_form() function in scheme_forms.py. This function takes in two arguments: expressions and env.

    expressions is going to be objects of class Pair representing our formals (just operators for the lambda function) and the second part is the operations.

    The variable formals is given to us: formals = expressions.first

    Scheme ———————

    (lambda (x y) (+x y))

    Python ———————–

    expressions = Pair(Pair(‘x’, Pair(‘y’, nil)), Pair(Pair(‘+’, Pair(‘x’, Pair(‘y’, nil))), nil))

    formals = Pair(‘x’, Pair(‘y’, nil)) #These are the arguments/operators to the lambda func

    expressions.rest = Pair(Pair(‘+’, Pair(‘x’, Pair(‘y’, nil))), nil) # the operations

    What we need to do is take the given information and return a LambdaProcedure object. The LambdaProcedure class is defined in scheme_classes.py. It would be very helpful to review it because you need to initialize and return an object from it.

    Hint: LambdaProcedure Class

    The code you write for this problem should be a single line long

    For more help

    Problem 8: Making New Frames

    In this problem we will be dealing with frames and the creation thereof. When we make a frame, we are initializing an object of class Frame. Each frame has bindings (a dict representing all the variables and values within a frame) and parent (the frame from which the new frame comes from).

    In Problem 1 we made the define() method that allowed us to define variables by saving them into the instance variable bindings. ! Remember this !

    For Problem 8, we are implementing the class method make_child_frame() which takes in two arguments: formals and vals.

    formals is a list of the symbols (the variables to which we are assigning values)

    vals is a list of the values we are assigning to the symbols in formals

    Scheme

    (define a 1)

    (define b 2)

    (define c 3)

    Python

    formals = Pair(‘a’, Pair(‘b’, Pair(‘c’, nil)))

    vals = Pair(‘a’, Pair(‘b’, Pair(‘c’, nil)))

    The CS 111 website gives four steps which are decently clear and pretty much make up the pseudo code for this problem:

    Hint: Assigning the Values

    Hint: Raise Error Syntax

    For more help

    For even more help

    And for even more, but less related help

    Problem 9: Lambda meets Frame

    This is another problem that should not require a lot of code, only two lines to be exact. In scheme_eval_apply.py we have the scheme_apply() function that applies procedures to arguments.

    scheme_apply() takes in procedure, args, and env. procedure is going to be an object of class Procedure. It could be a BuiltinProcedure or a LambdaProcedure (MuProcedure or MacroProcedure later too).

    procedure = LambdaProcedure(operators, operations, env)

    LambdaProcedure(Pair(‘x’, nil), Pair(Pair(‘*’, Pair(‘x’, Pair(‘x’, nil))), nil), <Global Frame>)

    args stores the values of the arguments that our procedure is going to be applied to. In the above box it would be the value that replaces the x’s in the LambdaProcedure.

    Scheme

    (define square (lambda (x) (* x x)))

    (square 21)

    Python

    args = Pair(21, nil)

    When we make a call to a lambda function, it opens a new frame in which the operators are defined and the operations take place. That means you need to make a new frame whose parent is the current frame. (First Line) Then you need to return an evaluation of all the body of the lambda function (the operations part) using eval_all(). (Second Line)

    Hint: SchemeError: unknown identifier: y

    Hint: Making New Frames

    Unfortunately there is no more help ):

    Problem 10: Defining Func’s Shorthandedly

    In Problem 10 we are going to edit the do_define_form() function that we wrote a part of in Problem 4. In Problem 4 we made it so that we could assign values to a variable name. Now we want to make it so we can assign functions to a variable name using the following syntax in Scheme:

    scm> (define (square x) (* x x))
    square
    scm> (square 2)
    4

    do_define_form() takes two arguments: expressions and env. expressions, as normal, is a list of objects from the class Pair. Consider the following example:

    Scheme

    (define (f x y) (+ x y))

    Python

    expressions =

    Pair(Pair(‘f’, Pair(‘x’, Pair(‘y’, nil))), Pair(Pair(‘+’, Pair(‘x’, Pair(‘y’, nil))), nil))

    You need to dissect expressions to get the function name, the operators, and the operations. Keep in mind we have the variable signature which is equal to the red highlighted portion of expressions above. To define the function we need to take the variable name and assign an object of class LambdaProcedure to it. To create this object we are going to use the function do_lambda_form() from Problem 7.

    As a reminder, do_lambda_form() takes in two arguments: expressions and env. It returns an object of class LambdaProcedure. expressions must be a scheme list represented by Pair class objects that hold the operators and the operations. You must create this Pair object in which the first part is the operators and the rest is the operations.

    Once you have the LambdaProcedure object, assign it to the variable name in the current frame.

    For more help

    Problem 11: The ‘Mu’

    The first important thing is to understand the difference between lexical and dynamic scoping. Here is the explanation again from the CS 111 website:

    CS 111 Website Description

    First, implement do_mu_form() in scheme_forms.py so that it returns an object of class MuProcedure. This should probably only be one line long. If you need help just look at your code for Problem 7. We are essentially doing the same thing except we are ignoring env because when initializing a MuProcedure we ignore the current frame because of dynamic scoping.

    Make sure to look at the __init__() for MuProcedure to see what it intakes as arguments:

    The class MuProcedure

    Here are what the arguments to the __init__() would look like if we were initializing a MuProcedure object based off of the given scheme expression:

    Scheme

    (define f (mu (x) (+ x y)))

    Python

    formals = Pair(‘x’, nil) #variable name

    body = Pair(Pair(‘+’, Pair(‘x’, Pair(‘y’, nil))), nil) #operations

    Second, you need to edit the scheme_apply() function in scheme_eval_apply.py for when the procedure is a MuProcedure. Return the evaluation of the body of the MuProcedure object, but remember you have to do that using the correct frame that results in dynamic scoping. So beforehand make a new frame based off of the current frame. Use this new frame when you evaluate the MuProcedure.

    Hint: Evaluating a Procedure

    Hint: Creating a New Frame

    For more help

    </end>

    Hopefully this was a sufficient help. Please submit any corrections or questions in the comments below. I will try my best to answer and update the article accordingly.

    Part 3

  • Guide to the Scheme Interpreter Project (BYU CS 111) Part 1

    Guide to the Scheme Interpreter Project (BYU CS 111) Part 1

    part 2

    The Scheme Interpreter project is the most daunting and if you’re me, by far the longest assignment (14 hours) in CS 111. In the project, you program bits and pieces of an interpreter for scheme in python. The project details and files can be found on the CS 111 website. Before beginning the project, I recommend reading the following chapters from Composing Programs: 3.2: Functional Programming, 3.4: Interpreters for Languages with Combination, and 3.5: Interpreters for Languages with Abstraction. Berkeley’s CS61a Youtube channel also has videos with helpful hints for specific questions from the scheme project.

    The project is divided into four parts: The Evaluator, Procedures, Special Forms, and Write Some Scheme. I will not be going over the last part, because I do not really like writing code in scheme.

    Problem 1: Define and Lookup

    The frame is the current environment of a program in which variables are defined. Calling a function creates a new child frame with its own variables and values. In this problem we will be creating the functions in python that will allow us to make variables and bind values to them.

    Our scheme interpreter (all of the python files) has a class, Frame, which will be where we make frames and control what variables and values are stored in them.

    The Frame class in scheme_classes.py

    When we initialize a frame object (__init__(self, parent)), it creates two instance variables: parent and bindings. Parent lets us know from which frame the newly initialized frame is being made. The first frame is the global frame so its parent is None. This is taken care of by the function create_global_frame() in scheme.py so don’t worry about it.

    bindings is a python dictionary that represents variables in scheme and their associated values.

    When we initialize a frame object, Bindings is an empty dictionary. To populate it, we need to implement the method define(self, symbol, value). The argument symbol is simply the variable name and value is the value to which symbol is being bound.

    Scheme

    (define a 3)

    symbol = ‘a’

    To Python

    define(‘a’, 3)

    value = 3

    To populate the dictionary, you could use the update({a: b}) method of python dictionaries.

    Now we need to implement the method lookup(self, symbol) which searches the frame object in bindings to see if the variable (symbol) is in there. If it is, it will return the value that the variable is bound to. If it is not in there, then it does the same search process but in the parent frame. Once we are to the global frame, meaning env.parent = None, if the variable is not found, the interpreter raises an error.

    Interpreter raises an error if variable is not found (scheme_classes.py)

    You can get the value of a dictionary key using the built-in .get(key_name) method. You can use python’s in to see if a key is in a dictionary.

    For more help

    Problem 2: Procedures

    This time we are going to be implementing a function in scheme_eval_apply.py called scheme_apply(). This function takes in a scheme list (args) and then applies the correct procedure (like addition or a lambda function) to args. The function returns a call to the correct procedure on args. Procedures are handled by the Procedure class in schemeclasses.py.

    The Procedure class in scheme_classes.py

    In Problem 2, we will be handling Built-in Procedures. Everytime a BuiltinProcedure is initialized, it creates three instance variables: name, py_func, and expect_env.

    py_func is a function in python that will handle the operation/procedure needing to be done in Scheme

    expect_env is a boolean (True or False) telling us if the built-in procedure needs the current environment information to run

    In scheme_apply(), args is a scheme list, meaning it is represented by the Pair class which is basically just a linked list.

    The CS 111 site gives pretty much step-by-step instructions on implementing this function properly.

    Hint: Scheme List to Python List

    Hint: Try Except Syntax

    For more help

    Problem 3: scheme_eval()

    In problem 3 we are going to evaluate the operator, then the operands (the arguments to the operator), and then apply the operator to all of the operands. This will be done in the function scheme_eval(expr). expr is a scheme expression represented by a Pair object.

    From Scheme

    (+ 2 2)

    The operator is (+) addition

    To Python

    expr = Pair(‘+’, Pair(2, Pair(2, nil)))

    The operands are 2 and 2

    The scheme_eval() function takes in expr. Your job is to get the operator in expr and recursively evaluate it using scheme_eval(). Then recursively evaluate all of the operands (the rest of expr after the operator) using scheme_eval(). Scheme_eval() is pre-programmed to be able to handle the operators and individual operands.

    The evaluation of the operator, will be a procedure. The final step is to apply the procedure on the operands using scheme_apply() from the last problem and return the result of that.

    Hint: Evaluating the Operands Using map()

    For more help

    Problem 4: Define Special Form

    In Problem 4, we will be tackling the do_define_form() function. This function takes two arguments: expr and env. expr is a scheme expression represented by Pair class objects.

    Scheme

    (define size 2)

    To Python

    expr = Pair(‘size’, Pair(2, nil))

    The first part of expr, ‘size‘, is the variable name. Whatever else that comes after is the expression or value to which the variable name will be bound. If it is an operation being defined, then the second part of expr, will start with an operator (like +).

    The variable pre-defined for us, signature = expressions.first, is just the name of the variable in scheme that we want to bind to a value. (In the above example, ‘x’) Your job is to write the code that takes the rest of the Scheme list (the Pair objects) and evaluates it to a value in Python. Then assign that value to signature in the current environment. Finally remember to return signature.

    Hint: Environment Class Method define()

    For more help

    Problem 5: quote

    In problem 5 we are going to handle the quote feature of scheme. If we call quote on an operand in scheme, then the operand will be returned, unevaluated.

    From the CS 111 Website Problem 5 Description

    All you need to do is just return the unevaluated operand. All it takes is a very short line of code. Personally, I spent about half an hour on this before I realized it, but I was also tired.

    If expressions = Pair(3, nil)

    Then return 3

    For more help

    </end>

    Hopefully this was a sufficient help. Please submit any corrections or questions in the comments below. I will try my best to answer and update the article accordingly.

    on to part 2