technology from back to front

Archive for June, 2011

Using goinstall for your own local code

I am working towards finishing a small project in go and my thoughts have turned to how I will package it up and release the code. The latest release of go has made some changes to goinstall so that code installed by you as a user can be kept separate from the base installation of go.

The first step in using goinstall is to create a directory structure for your local source, packages and binaries. This can be done like this

% cd ~/work
% mkdir -p gocode/src gocode/pkg gocode/bin

You can then create a GOPATH variable:

export GOPATH=~/work/gocode

Now any go projects can be placed in the $GOPATH/src directory and installed locally, you don’t even need to write makefiles.

For example:

% cd ~/work/gocode/src
% mkdir -p experiment/plutonium

Now create a file experiment.go in the directory:

package plutonium

import (
  "fmt"
)

func ExperimentOne(s string) string {
  return fmt.Sprintf("! DANGER ! %s ! DANGER !", s)
}

Now this code can be installed locally making it available to your other go projects:

% cd ~/work/gocode/src/experiment/plutonium
% goinstall .
% ls -l ~/work/gocode/pkg/linux_386/experiment
-rw-r--r-- 1 tim tim 9004 Jun 30 13:29 plutonium.a

You can also create executable programs:

% cd ~/work/gocode/src
% mkdir -p experiment/bang
% cd experiment/bang

Create a file called main.go:

package main

import (
  "experiment/plutonium"
  "log"
)

func main() {
  log.Print("Running experiment", plutonium.ExperimentOne("Highly dangerous"))
  log.Print("Careful now")
}

Install and run the program:

% cd ~/work/gocode/src/experiment/bang
% goinstall .
% cd ~/work/gocode/bin
% ./bang
2011/06/30 13:38:45 Running experiment! DANGER ! Highly dangerous ! DANGER !
2011/06/30 13:38:45 Careful now

So no Makefiles are needed! I would still create Makefiles because you will need them if you want to use gotest to run your unit tests.

by
tim
on
30/06/11

The Other Kind of Zipper

“A zipper is a[n editable] suspended walk.”[1]

Take a map: it takes some traversable structure, executes a function on each element, and returns a new traversable structure with the values obtained by applying the function to the elements of that structure.

Define a function that returns a pair (value, partial continuation) where the partial continuation represents the path taken to reach a particular value. This is a zipper on the given value.

It doesn’t particularly matter which control operators you use to get that partial continuation. shift/reset’s convenient because I’ve already implemented it, but Chung-chieh Shan showed that they’re all equally expressible.

Finally, give the map over the suspensible walk a function that composes the partial continuation with a “decider” function. This function takes some value and either returns that value, or the value of the node associated with the zipper.

This gives you a zipper on the first node. When you feed a value into the zipper, it returns you a new zipper, on the next node in your structure. When you’ve reached the end of your traversal, return a zipper that indicates that you’ve finished the traversal.

Hey presto, you have a zipper, derived from the traversal of an arbitrary structure.

So what’s that look like in Smalltalk?

Read more…

by
Frank Shearar
on

Automagic Phone-to-Kindle with Calibre

I’ve recently acquired a Kindle, and although it’s major use-case is for reading books, it’s also pretty good for reading long articles. This is particularly useful when I find out about said article via my phone (e.g. on Twitter) as my phone isn’t exactly good for reading anything really big. I started using the Send To Kindle app, but as it turns out that it does exactly what the name might suggest is actually a bad thing! The app attempts to do everything on it’s own, and as Amazon need to be sent an entire document to get stuff onto a Kindle, my phone gets tied up for multiple minutes in some cases, and that’s in the good case when I’ve got lots of bandwidth…

What would be a slightly more sensible option is just being able to send the URL of the article to Amazon, but as that isn’t an option, we need an intermediary, something else willing to do all the hard work of grabbing a page and sending it off for me. Read more…

by
Tom Parker
on
29/06/11

Zipping over Magritte-described Objects

Magritte is a metamodel description framework for Smalltalk, that is, a way of describing your domain objects. Having a description of your domain objects allows you to do a bunch of neat things, like automatically building a Seaside form for displaying an object.

If you’ve used C#’s ASP.Net MVC framework, you might think of the Magritte description as the collection of annotations your Model or ViewModel objects might have. Instead of

public class Person {
    [DisplayName("First Name")]
    public string FirstName { get; set; }

    [DisplayName("Last Name")]
    public string LastName { get; set; }
}

you have

Person class>>descriptionFirstName
    ^ MAStringDescription new
        label: 'First Name';
        yourself

Person class>>descriptionLastName
    ^ MAStringDescription new
        label: 'Last Name';
        yourself

Magritte allows you to describe more than how to render a field, or in what order to render fields. It allows you to describe how to access the parts of an object, whether directly calling its selector, plugging into a chain of accessors, or a memento-decorated object, and so on. Magritte can also describe the relationships between objects, like one-to-one or one-to-many.

Magritte provides us with a uniform way of accessing parts of an object, without resorting to reflection.

How would one zip over a tree of Magritte-described objects? Building on our previous work it’s not hard at all: we have an n-ary tree of objects. First, we make sure we fully annotate our domain objects with Magritte descriptions.

Next, we do two things: first, Magritte allows us to serialise all our children as an OrderedCollection:

MZBase>>children
    ^ self description children collect: [:each | each accessor read: self].

and so we can unserialise this collection as a newly-instantiated object:

Object>>withValues: aCollection
    ^ self new.

MZBase>>withValues: aCollection
    "Conceptually this mirrors Scala's apply, in a variadic manner."
    | o |
    "Create a new object, of the appropriate type."
    o := self new.
               
    "Initialise it. Each setter returns a _new instance_ so while functionally
     pure, this isn't exactly efficient."

    "#with:do: is a pair-wise version of #do:."
    o description children with: aCollection do:
            [:acc :val | o := acc accessor write: val to: o].
   
    ^ o.

We need to adjust our original TreeZipper, which had a few hard-coded bits. We change references to TreeZipper new to self class new, and instead of creating ZTrees with ZTree value: foo children: bar we allow subclasses to create their own objects: self newFocusOn: foo children: bar. In particular, we say

TreeZipper subclass: #MagritteZipper.

MagritteZipper>>newFocusOn: anObject children: aCollection
    ^ aCollection isEmpty
        ifTrue: [anObject]
        ifFalse: [anObject class withValues: aCollection].

We’re being a bit tricky here: if aCollection is empty, we have a “primitive” value – something with no subcomponents, like a number or a String[1] – while a non-empty aCollection indicates some composite object: an MZBase object.

And that’s it!

| p p2 z |
p := MZPerson firstName: 'Foo' lastName: 'Bar' at: (MZAddress at: 'foo').
z := MagritteZipper on: p.
p2 := ((z down changeTo: 'Barzzz') right changeTo: 'Brzz') root.
p2 firstName --> 'Barzzz'

As always, everything’s available at SqueakSource. Here’s the load script:

Installer ss
    project: 'Seaside31';
    install: 'Grease-Core-pmm.39';
    install: 'Grease-Pharo-Core-pmm.22'.

Installer lukas
    project: 'magritte2';
    install: 'Magritte-Model-fbs.405';
    install: 'Magritte-Pharo-Model-lr.22'.

Installer ss
    project: 'Zippers';
    install: 'Zippers-fbs.35'.

Installer ss
    project: 'MagZip';
    install: 'MagZip-fbs.2'.

[1] Yes, a String‘s actually an OrderedCollection of Character, but usually the individual characters aren’t interesting, so we treat it as a primitive value.

by
Frank Shearar
on
09/06/11

Search

Categories

You are currently browsing the LShift Ltd. blog archives for June, 2011.

Feeds

Archives

2000-14 LShift Ltd, 1st Floor, Hoxton Point, 6 Rufus Street, London, N1 6PE, UK+44 (0)20 7729 7060   Contact us