Skip to content
This repository has been archived by the owner on Jan 30, 2024. It is now read-only.

Commit

Permalink
Cosmetics and doc
Browse files Browse the repository at this point in the history
fix typos, add doc and sample code, change licence to eclipse.
  • Loading branch information
yloiseau authored and Julien Ponge committed Jun 25, 2015
1 parent 8b06d05 commit 6013627
Show file tree
Hide file tree
Showing 7 changed files with 166 additions and 63 deletions.
52 changes: 52 additions & 0 deletions doc/misc.asciidoc
Expand Up @@ -174,3 +174,55 @@ function main = |args| {

This example takes advantages of an executor augmentation and composable promises and futures to
compute Fibonacci numbers.


=== Lazy lists (`gololang.lazylist`) ===

This module defines a lazy list structure, as well as some utilities to work
with it.

A lazy list behaves like an _immutable_ linked list whose elements are evaluated
only when needed, as can be found in Haskell for example.

The next element in the list (the tail) is represented by a closure. The generated value
is cached so that the closure representing the next element is evaluated only once.

This is very useful when using higher order function such as `map`. Mapping
a long lazy list with a function and using only the 3 first elements will only
apply the function to these elements, as opposed to regular lists.

Since the tail closure will be called at most once, and we can't
guarantee when, or even if, it will be called, this closure must be
a pure, side-effect free, function.

Lazy lists can also be used to create infinite lists, also known as generators
(or anamorphisms).

Lastly, they allow for elegant recursive implementations of several classical
algorithms.

For instance, one can create a infinite lazy list containing integers as:

[source,golo]
----
function count = |start| -> cons(start, -> count(start + 1_L))
function count = -> count(0_L)
----

To construct a infinite list of all even multiples of 3, one can then use:

[source,golo]
----
let l = count(): map(|x| -> 3 * x): filter(|x| -> (x % 2) == 0)
----

The `cons` function returns a new lazy list whose head is its first argument,
and the tail its second.

A lazy list implement the `Collection`, interface, while remaining lazy. It is
thus possible to use it in imperative style with a `foreach` construct, or
recursively using `head` and `tail`.
On the other hand, functions or methods like `equals`, `size` or `contains` are
not very efficients, since they must evaluate the whole list, and thus negate
the laziness. They are here for completeness and compatibility with the regular
lists interface, but you should avoid such methods.
55 changes: 55 additions & 0 deletions samples/lazylist.golo
@@ -0,0 +1,55 @@
# ............................................................................................... #
#
# Copyright (c) 2012-2015 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
#
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at
# http://www.eclipse.org/legal/epl-v10.html
#
# ............................................................................................... #

module samples.LazyLists

import gololang.lazylist

----
create a lazy list of all integers
----
function count = |start| -> cons(start, -> cons(start + 1))

function useCount = {

# the list of all even multiples of 3
let l = count(): map(|x| -> 3 * x): filter(|x| -> (x % 2) == 0)
# nothing is computed yet

foreach v in l: take(10) {
println(v) # print the 10 first even multiples of 3
}
}


----
create a lazy range of integers
----
function lazyRange = |start, end| -> match {
when start >= end then emptyList()
otherwise cons(start, -> lazyRange(start + 1, end))
}

----
reimplementation of the map function
----
function myMap = |lst, func| -> match {
when lst: isEmpty() then emptyList()
otherwise cons(func(lst: head()), -> myMap(lst: tail(), func)))
}

# a lazy list of known values
let lst1 = cons(1, cons(2, cons(3, cons(4, emptyList()))))

# or simpler
let lst2 = lazyList(1, 2, 3, 4)


52 changes: 29 additions & 23 deletions src/main/golo/lazylist.golo
@@ -1,40 +1,39 @@
# ............................................................................................... #
#
# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
# Copyright (c) 2012-2015 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at
# http://www.eclipse.org/legal/epl-v10.html
#
# ............................................................................................... #

----
This module defines utility functions and augmentations to ease the use of
the `gololang.LazyList` object.
A lazy list is a *immutable* list that is evaluated only when needed, as can be
found in Haskell for example.
A lazy list is an *immutable* list whose elements are evaluated only when needed,
as can be found in Haskell for example.
This is very useful when using higher order function such as `map`. Mapping
long a lazy list with a function and using only the 3 first elements will only
apply the function to these elements, as oposed to regular lists.
a long lazy list with a function and using only the 3 first elements will only
apply the function to these elements, as opposed to regular lists.
Lazy lists can also be used to create infinite lists or generators.
Lazy lists can also be used to create infinite lists, also known as generators
(or anamorphisms).
Lastly, they allow for elegant recursive implementations of several classical
algorithms.
For instance, one can create a infinite lazy list containing integers as:
function count = |start| -> cons(start, -> count(start + 1_L))
function count = -> count(0_L)
On the other hand, functions or methods like `equals`, `size` or `contains` are
not very efficients, since they must evaluate the whole list, and thus negate
the lazyness. They are here for completeness and compatibility with the regular
the laziness. They are here for completeness and compatibility with the regular
lists interface, but you should avoid such methods.
Some functions in this module are recursive (re)implementation of standard list
Expand Down Expand Up @@ -108,10 +107,17 @@ function fromIter = |it| -> match {
}

augment java.lang.Iterable {
----
Returns a lazy list from this `Iterable`. Can be used for instance to lazily
map a list.
----
function asLazyList = |this| -> iteratorToLazyList(this: iterator())
}

augment java.util.Iterator {
----
Returns a lazy list view of this `Iterator`.
----
function asLazyList = |this| -> iteratorToLazyList(this)
}

Expand Down Expand Up @@ -177,7 +183,7 @@ augment gololang.LazyList {
}

----
Join the elements into a string:
Joins the elements into a string:
println(list[1, 2, 3]: join(", "))
Expand All @@ -202,9 +208,9 @@ augment gololang.LazyList {
}

----
Generator function on lazy lists.
Generator function on lazy lists (anamorphism).
This function generate a (possibly infinite) lazy list. Starting with the
This function generates a (possibly infinite) lazy list. Starting with the
`seed` value, if `finished(seed)` is `true`, the generation stops and an empty
list is returned. Otherwise, `unspool` is called on `seed`, and must generate
two values: the head of the list (current value) and the next seed that will be
Expand Down Expand Up @@ -241,7 +247,7 @@ no parameters, and it's used to produce the values (called for each `tail`
access).
For instance, `repeat(5)` will return an infinite lazy list of `5`s, and
`repeate(^f)` will return a infinte lazy list of calls to `f`
`repeat(^f)` will return a infinite lazy list of calls to `f`
([f(), f(), f(), ...])
* `value`: a value or a closure
Expand All @@ -254,7 +260,7 @@ function repeat = |value| -> match {
----
Returns an infinite lazy list produced by iterative application of a function
to an initial element.
`iterate(z, f)` thus yield `z, f(z), f(f(z)), ...`
`iterate(z, f)` thus yields `z, f(z), f(f(z)), ...`
For instance, one can create a infinite list of integers using:
Expand Down
17 changes: 5 additions & 12 deletions src/main/java/gololang/HeadTail.java
@@ -1,17 +1,10 @@
/*
* Copyright 2012-2015 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
* Copyright (c) 2012-2015 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/

package gololang;
Expand Down
25 changes: 9 additions & 16 deletions src/main/java/gololang/LazyList.java
@@ -1,17 +1,10 @@
/*
* Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
* Copyright (c) 2012-2015 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/

package gololang;
Expand All @@ -27,11 +20,11 @@
* <p>
* A lazy list behaves like a linked list, but each next element
* is represented by a closure that is evaluated only if needed.
* The value is memoized, so that the closure representing the tail
* is evaluated only once.
* The value is cached, so that the closure representing the tail
* is evaluated only once.
*
* Since the tail closure will be called at most once, and we can't
* guarantee when, or even if, it will be called, this closure must be
* Since the tail closure will be called at most once, and we can't
* guarantee when, or even if, it will be called, this closure must be
* a pure, side-effect free, function.
*/
public class LazyList implements Collection<Object>, HeadTail<Object> {
Expand Down
17 changes: 5 additions & 12 deletions src/test/java/gololang/LazyListTest.java
@@ -1,17 +1,10 @@
/*
* Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
* Copyright (c) 2012-2015 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/

package gololang;
Expand Down
11 changes: 11 additions & 0 deletions src/test/resources/for-test/lazylist.golo
@@ -1,3 +1,14 @@
# ............................................................................................... #
#
# Copyright (c) 2012-2015 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
#
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at
# http://www.eclipse.org/legal/epl-v10.html
#
# ............................................................................................... #

module golo.test.LazyList

import gololang.lazylist
Expand Down

0 comments on commit 6013627

Please sign in to comment.