#light
let g = new System.Random()
let s = Seq.init_infinite (fun _ -> g.NextDouble())
/// You thought 'a seq is Haskell [a]? Not quite! It does not memoize:
printfn "%A" (Seq.hd s, Seq.hd s) (* Surprise! fst and snd differ! *)
type X =
static member X = g.NextDouble()
/// You thought X is a value? Not quite! It is a property (think function):
printfn "%A" (X.X, X.X) (* Surprise! fst and snd differ! *)
Friday, March 6, 2009
F#: Haskellers beware!
Thursday, March 5, 2009
F# interface implementation - is `unit` special?
#light
type 'a A =
interface
abstract member A : unit -> 'a
end
let x = { new int A with member x.A() = 1 } // ALLOWED
let y = { new unit A with member x.A() = () } // ERROR?
Cyrillic typesetting in LaTeX on Arch
foo.tex:
\documentclass{article}
\usepackage[T2A]{fontenc}
\usepackage[utf8x]{inputenc}
\usepackage[russian]{babel}
\usepackage{ucs}
\begin{document}
Привет, мир!
\end{document}
Then pdflatex foo.tex.
Arch package required: texlive-langcyrillic.
Wednesday, March 4, 2009
F# Quirks
A feature or a bug?
An innocent-looking pair of parentheses ends up influencing the runtime representation of discriminated union types.
I would prefer not to have this. The two representations seem conceptually redundant, it would be better to just pick the faster one.
Given this foo.fs:
#light
open Microsoft.FSharp.Reflection
type A1 = A1 | B1 of (A1 * A1)
type A2 = A2 | B2 of A2 * A2
printfn "%A" ((FSharpType.GetUnionCases(typeof<A1>)
|> Array.map (fun x -> x.GetFields())));;
printfn "%A" ((FSharpType.GetUnionCases(typeof<A2>)
|> Array.map (fun x -> x.GetFields())));;
Run fsi --quiet --exec foo.fs to produce this:
[|[||]; [|Microsoft.FSharp.Core.Tuple`2[FSI_0001.Foo+A1,FSI_0001.Foo+A1] B11|]|]
[|[||]; [|FSI_0001.Foo+A2 B21; FSI_0001.Foo+A2 B22|]|]
I found this code while testing a library that produced different results depending on the presence or absence of the parentheses.
Update: A feature! Thanks to Zedd. I should know my specs and my OCaml:
Objective Caml version 3.10.2 # type c = C of int * int;; type c = C of int * int # match C(1, 2) with | C x -> x;; The constructor C expects 2 argument(s), but is here applied to 1 argument(s) # type c = C of (int * int);; type c = C of (int * int) # match C(1, 2) with | C x -> x;; - : int * int = (1, 2) #
Saturday, February 28, 2009
Friday, February 27, 2009
hdaemonize on hackage
Having got a green light from Andre, I uploaded hdaemonize to Hackage.
I also cleaned up the library a bit. Reading up on POSIX signals I decided that it is wrong for the daemonize library to mess with them beyond blocking HUP. Also, now it has two functions, daemonize :: IO () -> IO () which does the bare minimum, and serviced :: Program -> IO () that does that and more, for example writing a PID file, handling start/stop/restart, catching and logging exceptions to syslog.
Time to try it out in production.
R Language - once more
An early warning for the unwary hacker.
Normal-order evaluation
Y <- function (f)
(function (x) f(x(x))) (function (x) f(x(x)))
FAC <- function (f) function(n)
(if (n == 0) 1 else n * f(n - 1))
> Y(fac)(10)
[1] 3628000
Quoting and macros
fn <- function(x) {
x <- substitute(x);
f <- list(NULL, x[[2]]);
names(f) <- c(x[[3]], "");
as.function(f, envir=parent.frame());
}
y <- fn(f -> fn(x -> f(x(x)))(fn(x -> f(x(x)))))
fac <- fn(f -> fn(n -> if (n == 0) 1 else n * f(n - 1)))
> y(fac)(10)
[1] 3628800
Coercions
> NULL == FALSE
logical(0)
If you are wondering what happened here, FALSE, which is a logical vector of length 1, was compared for equality with NULL, which is an empty list. To proceed with the comparison, R coerced the list to a vector of length 0. Then, two logical vectors were compared elementwise for equality, to yield the resulting vector of length 0.
Equational reasoning is not a good starting point to make sense of this:
> NULL == NULL
logical(0)
> logical(0) == FALSE
logical(0)
Side effects
> f <- function () { print("MISSILES LAUNCHED"); 1 }
> g <- function (x <- f()) { x + 1 }
> g()
[1] "MISSILES LAUNCHED"
[1] 2
> g(1)
[1] 2
Argument parsing
> f <- function (x = y + 1, y = x + 1) { y <- 2; y }
> f()
[1] 2
Summary
Can a language safely combine the above features?
Does statistics really nead such a language?
References
- Lumley T. "Programmer's Niche: Macros in {R}", R News, 2001, Vol 1, No. 3, pp 11–13
- Sungwoo Park. A critique of R. Invited talk at Japanese R Users' Meeting, December 2006
- R Language Definition