Skip to content

Commit 95d1d33

Browse files
committed
update file structure, readme partially edited
1 parent d36c25d commit 95d1d33

26 files changed

+1503
-0
lines changed

docs/lib/empty.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/**
2+
* This file is empty and only exists to satisfy JSDoc when building the landing page.
3+
*/

docs/lib/list.py

Lines changed: 365 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,365 @@
1+
def pair(x, y):
2+
"""
3+
PRIMITIVE
4+
Makes a pair whose head (first component) is x and whose
5+
tail (second component) is y.
6+
7+
Parameters:
8+
x (value): given head
9+
y (value): given tail
10+
11+
Returns:
12+
pair: pair with x as head and y as tail
13+
"""
14+
pass
15+
16+
17+
def is_pair(x):
18+
"""
19+
PRIMITIVE
20+
Returns true if x is a pair and false otherwise.
21+
22+
Parameters:
23+
x (value): given value
24+
25+
Returns:
26+
boolean: whether x is a pair
27+
"""
28+
pass
29+
30+
31+
def head(p):
32+
"""
33+
PRIMITIVE
34+
Returns head (first component) of given pair p.
35+
36+
Parameters:
37+
p (pair): given pair
38+
39+
Returns:
40+
value: head of p
41+
"""
42+
pass
43+
44+
45+
def tail(p):
46+
"""
47+
PRIMITIVE
48+
Returns tail (second component) of given pair p.
49+
50+
Parameters:
51+
p (pair): given pair
52+
53+
Returns:
54+
value: tail of p
55+
"""
56+
pass
57+
58+
59+
def is_none(x):
60+
"""
61+
PRIMITIVE
62+
Returns true if x is the empty linked list None, and false otherwise.
63+
64+
Parameters:
65+
x (value): given value
66+
67+
Returns:
68+
boolean: whether x is None
69+
"""
70+
pass
71+
72+
73+
def is_linked_list(xs):
74+
"""
75+
PRIMITIVE
76+
Returns true if xs is a linked list as defined in the textbook, and
77+
false otherwise.
78+
79+
Parameters:
80+
xs (value): given value
81+
82+
Returns:
83+
boolean: whether xs is a linked list
84+
"""
85+
pass
86+
87+
88+
def linked_list(*values):
89+
"""
90+
PRIMITIVE
91+
Given n values, returns a linked list of length n. The elements of
92+
the linked list are the given values in the given order.
93+
94+
Parameters:
95+
value (value1, value2, ...values): given values
96+
97+
Returns:
98+
linked list: linked list containing all values
99+
"""
100+
pass
101+
102+
103+
def draw_data(value1, value2, *values):
104+
"""
105+
PRIMITIVE
106+
Visualizes the arguments in a separate drawing area in the Source
107+
Academy using box-and-pointer diagrams.
108+
109+
Parameters:
110+
value1 (value1, value2, ...values): given values
111+
"""
112+
pass
113+
114+
115+
def equal(xs, ys):
116+
"""
117+
Pure Function: Returns true if both have the same structure (pairs)
118+
and identical values at corresponding leaf positions.
119+
"""
120+
if is_pair(xs):
121+
return (
122+
is_pair(ys)
123+
and equal(head(xs), head(ys))
124+
and equal(tail(xs), tail(ys))
125+
)
126+
elif is_none(xs):
127+
return is_none(ys)
128+
elif is_int(xs):
129+
return is_int(ys) and xs == ys
130+
elif is_float(xs):
131+
return is_float(ys) and xs == ys
132+
elif is_boolean(xs):
133+
return is_boolean(ys) and ((xs and ys) or (not xs and not ys))
134+
elif is_string(xs):
135+
return is_string(ys) and xs == ys
136+
else:
137+
return False
138+
139+
140+
def length(xs):
141+
"""
142+
Returns the length of the linked list xs.
143+
"""
144+
return _length(xs, 0)
145+
146+
147+
def _length(xs, acc):
148+
return acc if is_none(xs) else _length(tail(xs), acc + 1)
149+
150+
151+
def map_linked_list(f, xs):
152+
"""
153+
Returns a linked list that results from linked list xs by element-wise
154+
application of unary function f.
155+
"""
156+
return _map_linked_list(f, xs, None)
157+
158+
159+
def _map_linked_list(f, xs, acc):
160+
return (
161+
reverse(acc)
162+
if is_none(xs)
163+
else _map_linked_list(f, tail(xs), pair(f(head(xs)), acc))
164+
)
165+
166+
167+
def build_linked_list(fun, n):
168+
"""
169+
Makes a linked list with n elements by applying the unary function fun
170+
to the numbers 0 to n - 1.
171+
"""
172+
return _build_linked_list(n - 1, fun, None)
173+
174+
175+
def _build_linked_list(i, fun, already_built):
176+
return (
177+
already_built
178+
if i < 0
179+
else _build_linked_list(i - 1, fun, pair(fun(i), already_built))
180+
)
181+
182+
183+
def for_each(fun, xs):
184+
"""
185+
Applies the unary function fun to every element of the linked list xs.
186+
"""
187+
if is_none(xs):
188+
return True
189+
else:
190+
fun(head(xs)) # Side effect happens here if fun is not pure
191+
return for_each(fun, tail(xs))
192+
193+
194+
def linked_list_to_string(xs):
195+
"""
196+
Returns a string that represents linked list xs using the text-based
197+
box-and-pointer notation.
198+
"""
199+
return _linked_list_to_string(xs, lambda x: x)
200+
201+
202+
def _linked_list_to_string(xs, cont):
203+
if is_none(xs):
204+
return cont("None")
205+
elif is_pair(xs):
206+
return _linked_list_to_string(
207+
head(xs),
208+
lambda x_str: _linked_list_to_string(
209+
tail(xs), lambda y_str: cont(f"[{x_str},{y_str}]")
210+
),
211+
)
212+
else:
213+
return cont(stringify(xs))
214+
215+
216+
def reverse(xs):
217+
"""
218+
Returns linked list xs in reverse order.
219+
"""
220+
return _reverse(xs, None)
221+
222+
223+
def _reverse(original, reversed_acc):
224+
return (
225+
reversed_acc
226+
if is_none(original)
227+
else _reverse(tail(original), pair(head(original), reversed_acc))
228+
)
229+
230+
231+
def append(xs, ys):
232+
"""
233+
Returns a linked list that results from appending the linked list ys
234+
to the linked list xs.
235+
"""
236+
return _append(xs, ys, lambda x: x)
237+
238+
239+
def _append(xs, ys, cont):
240+
return (
241+
cont(ys)
242+
if is_none(xs)
243+
else _append(tail(xs), ys, lambda zs: cont(pair(head(xs), zs)))
244+
)
245+
246+
247+
def member(v, xs):
248+
"""
249+
Returns first postfix sub-linked list whose head is identical to v
250+
(using ==). Returns None if the element does not occur in the linked
251+
list.
252+
"""
253+
if is_none(xs):
254+
return None
255+
elif v == head(xs):
256+
return xs
257+
else:
258+
return member(v, tail(xs))
259+
260+
261+
def remove(v, xs):
262+
"""
263+
Returns a linked list that results from xs by removing the first item
264+
from xs that is identical (==) to v.
265+
"""
266+
return _remove(v, xs, None)
267+
268+
269+
def _remove(v, xs, acc):
270+
if is_none(xs):
271+
return append(reverse(acc), xs)
272+
elif v == head(xs):
273+
return append(reverse(acc), tail(xs))
274+
else:
275+
return _remove(v, tail(xs), pair(head(xs), acc))
276+
277+
278+
def remove_all(v, xs):
279+
"""
280+
Returns a linked list that results from xs by removing all items from
281+
xs that are identical (==) to v.
282+
"""
283+
return _remove_all(v, xs, None)
284+
285+
286+
def _remove_all(v, xs, acc):
287+
if is_none(xs):
288+
return append(reverse(acc), xs)
289+
elif v == head(xs):
290+
return _remove_all(v, tail(xs), acc)
291+
else:
292+
return _remove_all(v, tail(xs), pair(head(xs), acc))
293+
294+
295+
def enum_linked_list(start, end):
296+
"""
297+
Makes a linked list with elements from start to end (inclusive).
298+
"""
299+
return _enum_linked_list(start, end, None)
300+
301+
302+
def _enum_linked_list(start, end, acc):
303+
return (
304+
reverse(acc)
305+
if start > end
306+
else _enum_linked_list(start + 1, end, pair(start, acc))
307+
)
308+
309+
310+
def list_ref(xs, n):
311+
"""
312+
Returns the element of linked list xs at position n (0-indexed).
313+
"""
314+
if n == 0:
315+
if is_none(xs):
316+
raise IndexError(
317+
"linked_list_ref: index out of bounds on None linked list"
318+
)
319+
return head(xs)
320+
else:
321+
if is_none(xs):
322+
raise IndexError("linked_list_ref: index out of bounds")
323+
return list_ref(tail(xs), n - 1)
324+
325+
326+
def accumulate_linked_list(f, initial, xs):
327+
"""
328+
Applies binary function f to the elements of xs from right-to-left
329+
order.
330+
"""
331+
return _accumulate_linked_list(f, initial, xs, lambda x: x)
332+
333+
334+
def _accumulate_linked_list(f, initial, xs, cont):
335+
if is_none(xs):
336+
return cont(initial)
337+
else:
338+
# Recursive CPS call: Process tail, then apply f with head,
339+
# then pass to continuation
340+
return _accumulate_linked_list(
341+
f,
342+
initial,
343+
tail(xs),
344+
lambda x_accumulated_from_tail: cont(
345+
f(head(xs), x_accumulated_from_tail)
346+
),
347+
)
348+
349+
350+
def filter_linked_list(pred, xs):
351+
"""
352+
Returns a linked list that contains only those elements for which the
353+
one-argument function pred returns true.
354+
"""
355+
return _filter_linked_list(pred, xs, None)
356+
357+
358+
def _filter_linked_list(pred, xs, acc):
359+
if is_none(xs):
360+
return reverse(acc)
361+
else:
362+
if pred(head(xs)):
363+
return _filter_linked_list(pred, tail(xs), pair(head(xs), acc))
364+
else:
365+
return _filter_linked_list(pred, tail(xs), acc)

docs/lib/ruff.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
line-length = 80

0 commit comments

Comments
 (0)