Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Immutable ordered finite maps and sets #561

Draft
wants to merge 16 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion effekt/jvm/src/test/scala/effekt/StdlibTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ abstract class StdlibChezTests extends StdlibTests {
examplesDir / "stdlib" / "bytearray",
examplesDir / "stdlib" / "io",
examplesDir / "stdlib" / "stream" / "characters.effekt",
examplesDir / "stdlib" / "stream" / "fuse_newlines.effekt"
examplesDir / "stdlib" / "stream" / "fuse_newlines.effekt",
examplesDir / "stdlib" / "map",
examplesDir / "stdlib" / "set",
)
}
class StdlibChezSchemeMonadicTests extends StdlibChezTests {
Expand Down Expand Up @@ -65,5 +67,9 @@ class StdlibLLVMTests extends StdlibTests {
examplesDir / "stdlib" / "list" / "build.effekt",
examplesDir / "stdlib" / "string" / "strings.effekt",
examplesDir / "stdlib" / "string" / "unicode.effekt",

// Not implemented yet
examplesDir / "stdlib" / "map",
examplesDir / "stdlib" / "set",
)
}
7 changes: 7 additions & 0 deletions examples/stdlib/map/counter.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
ask: 3
can: 3
you: 3
see: 0
do: 4
Effekt: 2
[Effekt → 2, and → 1, ask → 3, but → 1, can → 3, do → 4, fellow → 2, for → 4, language → 2, man → 1, my → 2, not → 2, of → 2, programmers → 2, programs → 1, so → 1, the → 2, together → 1, we → 1, what → 4, will → 1, world → 1, you → 3, your → 2]
39 changes: 39 additions & 0 deletions examples/stdlib/map/counter.effekt
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import map

def counter(words: List[String]): Map[String, Int] = {
var m: Map[String, Int] = map::empty();

list::foreach(words) { word =>
m = m.putWithKey(word, 1) { (_, n1, n2) => n1 + n2 }
}

m
}

def main() = {
// John F. Kennedy's Inaugural Address, Jan 20, 1961; modified for Effekt
val speech: List[String] = [
"and", "so", "my", "fellow", "Effekt", "programmers",
"ask", "not", "what", "your", "language", "can", "do", "for", "you",
"ask", "what", "you", "can", "do", "for", "your", "language",
"my", "fellow", "programmers", "of", "the", "world",
"ask", "not", "what", "Effekt", "will", "do", "for", "you",
"but", "what", "together", "we", "can", "do", "for", "the", "programs", "of", "man"
]

val ctr: Map[String, Int] = counter(speech)

def test(word: String) = {
val count = ctr.getOrElse(word) { 0 }
println(word ++ ": " ++ count.show)
}

test("ask")
test("can")
test("you")
test("see")
test("do")
test("Effekt")

println(map::internal::prettyPairs(ctr.toList))
}
7 changes: 7 additions & 0 deletions examples/stdlib/map/map.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[0 → Hello, 1 → World, 2 → Woo!]
[-1 → Hullo, 0 → Hello, 1 → World, 2 → Woo!]
[-10 → EY, -1 → Hullo, 0 → Hello, 1 → World, 2 → Woo!]
[0 → Hello, 2 → Woo!, 42 → Whole new world!, 100 → Big, 1000 → Bigger, 10000 → Biggest!]
[-1 → Huh?!, 0 → Hello, 1 → Foo, 2 → Woo!, 42 → Whole new world!, 100 → Big, 1000 → Bigger, 10000 → Biggest!]
[-1 → Huh?!, 0 → Hello, 1 → Foo, 2 → Woo!, 42 → Whole new world!, 100 → Big, 1000 → Bigger, 10000 → Biggest!]
[0 → Hello, 1 → World, 2 → Woo!]
28 changes: 28 additions & 0 deletions examples/stdlib/map/map.effekt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import map

def main() = {
val l = [(0, "Hello"), (1, "World"), (2, "Woo!")]

val m = map::fromList(l)
println(map::internal::prettyPairs(m.toList))

val m2 = m.put(-1, "Hullo")
println(map::internal::prettyPairs(m2.toList))

val m3 = m2.put(-10, "EY")
println(map::internal::prettyPairs(m3.toList))

// ...

val m4 = m.delete(1).put(42, "Whole new world!").put(100, "Big").put(1000, "Bigger").put(10000, "Biggest!")
println(map::internal::prettyPairs(m4.toList))

val m5 = map::fromList(Cons((1, "Foo"), Cons((-1, "Huh?!"), m4.toList.reverse)))
println(map::internal::prettyPairs(m5.toList))

val m6: Map[Int, String] = m5.toList.fromList
println(map::internal::prettyPairs(m6.toList))

val nuMap = map::fromList(l.reverse)
println(map::internal::prettyPairs(nuMap.toList))
}
22 changes: 22 additions & 0 deletions examples/stdlib/set/unique.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
ask: true
can: true
you: true
see: false
do: true
Effekt: true

Cons(Effekt, Cons(and, Cons(ask, Cons(but, Cons(can, Cons(do, Cons(fellow, Cons(for, Cons(language, Cons(man, Cons(my, Cons(not, Cons(of, Cons(programmers, Cons(programs, Cons(so, Cons(the, Cons(together, Cons(we, Cons(what, Cons(will, Cons(world, Cons(you, Cons(your, Nil()))))))))))))))))))))))))
sorted
Cons(Effekt, Cons(and, Cons(ask, Cons(but, Cons(can, Cons(do, Cons(fellow, Cons(for, Cons(language, Cons(man, Cons(my, Cons(not, Cons(of, Cons(programmers, Cons(programs, Cons(so, Cons(the, Cons(together, Cons(we, Cons(what, Cons(will, Cons(world, Cons(you, Cons(your, Nil()))))))))))))))))))))))))
sorted

Cons(after, Cons(around, Cons(better, Cons(do, Cons(ever, Cons(faster, Cons(harder, Cons(hour, Cons(is, Cons(it, Cons(make, Cons(makes, Cons(more, Cons(never, Cons(over, Cons(stronger, Cons(than, Cons(the, Cons(us, Cons(work, Cons(world, Nil())))))))))))))))))))))
sorted
lyrics / speech:
Cons(after, Cons(around, Cons(better, Cons(ever, Cons(faster, Cons(harder, Cons(hour, Cons(is, Cons(it, Cons(make, Cons(makes, Cons(more, Cons(never, Cons(over, Cons(stronger, Cons(than, Cons(us, Cons(work, Nil()))))))))))))))))))
speech / lyrics:
Cons(Effekt, Cons(and, Cons(ask, Cons(but, Cons(can, Cons(fellow, Cons(for, Cons(language, Cons(man, Cons(my, Cons(not, Cons(of, Cons(programmers, Cons(programs, Cons(so, Cons(together, Cons(we, Cons(what, Cons(will, Cons(you, Cons(your, Nil())))))))))))))))))))))
speech n lyrics:
Cons(do, Cons(the, Cons(world, Nil())))
speech u lyrics:
Cons(Effekt, Cons(after, Cons(and, Cons(around, Cons(ask, Cons(better, Cons(but, Cons(can, Cons(do, Cons(ever, Cons(faster, Cons(fellow, Cons(for, Cons(harder, Cons(hour, Cons(is, Cons(it, Cons(language, Cons(make, Cons(makes, Cons(man, Cons(more, Cons(my, Cons(never, Cons(not, Cons(of, Cons(over, Cons(programmers, Cons(programs, Cons(so, Cons(stronger, Cons(than, Cons(the, Cons(together, Cons(us, Cons(we, Cons(what, Cons(will, Cons(work, Cons(world, Cons(you, Cons(your, Nil()))))))))))))))))))))))))))))))))))))))))))
103 changes: 103 additions & 0 deletions examples/stdlib/set/unique.effekt
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import set

def unique(words: List[String]): Set[String] = {
var s: Set[String] = set::empty();

list::foreach(words) { word =>
s = s.insert(word)
}

s
}

def main() = {
// John F. Kennedy's Inaugural Address Jan 20 1961; modified for Effekt
val speech: List[String] = [
"and", "so", "my", "fellow", "Effekt", "programmers",
"ask", "not", "what", "your", "language", "can", "do", "for", "you",
"ask", "what", "you", "can", "do", "for", "your", "language",
"my", "fellow", "programmers", "of", "the", "world",
"ask", "not", "what", "Effekt", "will", "do", "for", "you",
"but", "what", "together", "we", "can", "do", "for", "the", "programs", "of", "man"
]

val uniqueSpeech: Set[String] = unique(speech)

def test(word: String) = {
val present = uniqueSpeech.contains(word)
println(word ++ ": " ++ present.show)
}

test("ask")
test("can")
test("you")
test("see")
test("do")
test("Effekt")

// ---
println("")

def testSorted(s: Set[String]) = {
val sorted = s.toList.isSortedBy { (x, y) => x <= y }
if (sorted) {
println("sorted")
} else {
println("unsorted")
}
}

println(uniqueSpeech.toList)
testSorted(uniqueSpeech)

println(set::fromList(speech).toList)
testSorted(set::fromList(speech))

// ---
println("")

// Around the World / Harder, Better, Faster, Stronger by Daft Punk (Alive 2007)
val lyrics: List[String] = [
"around", "the", "world", "around", "the", "world",
"around", "the", "world", "around", "the", "world",
"around", "the", "world", "around", "the", "world",
"around", "the", "world", "around", "the", "world",
"around", "the", "world", "around", "the", "world",
"around", "the", "world", "around", "the", "world",
"around", "the", "world", "around", "the", "world",
"around", "the", "world", "around", "the", "world",

"work", "it", "make", "it", "do", "it", "makes", "us",
"harder", "better", "faster", "stronger",
"more", "than", "hour", "hour", "never",
"ever", "after", "work", "is", "over",

"work", "it", "make", "it", "do", "it", "makes", "us",
"around", "the", "world", "around", "the", "world",
"around", "the", "world", "around", "the", "world",

"harder", "better", "faster", "stronger",
"around", "the", "world", "around", "the", "world",
"around", "the", "world", "around", "the", "world"
]

val uniqueLyrics = unique(lyrics)

println(uniqueLyrics.toList)
testSorted(uniqueLyrics)

// ---
println("")

println("lyrics / speech:")
println(uniqueLyrics.difference(uniqueSpeech).toList)

println("speech / lyrics:")
println(uniqueSpeech.difference(uniqueLyrics).toList)

println("speech n lyrics:")
println(uniqueLyrics.intersection(uniqueSpeech).toList)

println("speech u lyrics:")
println(uniqueLyrics.union(uniqueSpeech).toList)
}
7 changes: 7 additions & 0 deletions examples/stdlib/stream/map.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
1: H (72)
2: e (101)
3: l (108)
4: l (108)
5: o (111)
[1 → H, 2 → e, 3 → l, 4 -> l, 5 -> o]
hello
17 changes: 17 additions & 0 deletions examples/stdlib/stream/map.effekt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import stream
import map

def main() = {
val m = map::fromList([(1, 'H'), (2, 'e'), (3, 'l'), (4, 'l'), (5, 'o')])

for[(Int, Char)] { each(m) } { case (k, v) =>
println(show(k) ++ ": " ++ show(v) ++ " (" ++ show(v.toInt) ++ ")")
}

val newMap = collectMap[Int, Char] { each(m) }
println(map::internal::prettyPairs(newMap.toList))

val hello: String = collectString { eachValue(m) }
println(hello)
}

Loading
Loading