Sunday, January 2, 2011

jni4net 0.8.2 - bugfix release

Bug fixes

  • upgraded nMaven, NUnit, made build 32bit only
  • fixed throwing exceptions for missing proxy classes
  • [#18] - C# string[]{null} -> JVM -> null reference exception
  • improved architecture detection

Sunday, November 7, 2010

jni4net 0.8.1 - bugfix release

  • Fixed memory leak reported by Jaco Ackermann
  • Included improved CLR detection contributed by Leonid Bogdanov
Download 0.8.1 here

Thursday, September 23, 2010

Decomposition in functional languages

Got an idea: functions (in FP) could be composed similar was as components in OOP. For example with dependency injection. For components in OOP we use interfaces. For functions we could use delegates. To achieve decomposition and modularity.
I tried to find something about it. No luck. Probably because there are no functional programs big enough to need this ?
While searching for enterprise scale applications written in FP I found this list. Functional Programming in the Real World and this paper

I hope I just missed the killer application for FP, which would be big enough to deserve decomposition. Maybe someone could find me answer at stack overflow.

Tuesday, July 20, 2010

CLR 4.0 for Robocode

I finally got motivated by Justin and Jason to do something for Robocode .NET again. I upgraded it to jni4net 0.8. This means Robocode will prefer CLR 4.0 if installed and then will run robots written in C# 4.0 or F#. I also implemented Robocode Control API for .NET. I piggyback to Flemming's working branch, hope he will not kill me once he returns from holidays :-D

Download preview is there, Alpha quality.
robocode-1.7.2.2-Alpha-setup.jar
robocode.dotnet-1.7.2.2-Alpha-setup.jar

MyFirstRobot.F#

I really like the syntax.
namespace SampleFs
open Robocode
type MyFirstRobot() = 
    inherit Robot()
    override robot.Run() = 
            while true do
                robot.TurnLeft(40.0)
                robot.Ahead(20.0)
    override robot.OnScannedRobot(evnt : ScannedRobotEvent) = 
            robot.Fire(1.0)
    override robot.OnHitByBullet(evnt : HitByBulletEvent) = 
            robot.TurnLeft(90.0 - evnt.Bearing)

Sunday, May 30, 2010

Learning F# with Project Euler - day 2

Problem 4

open Microsoft.FSharp.Core.Operators
let findpalindrome xs ys =
    let separate s p = (s % (pown 10 (p+1))) - (s % (pown 10 p))
    let shiftl s p o = (separate s p) / (pown 10 (p-o))
    let shiftr s p o = (separate s p) * (pown 10 (o-p))
    let flip f = shiftl f 5 0 + shiftl f 4 1 + shiftl f 3 2 + shiftr f 2 3 + shiftr f 1 4 + shiftr f 0 5
    let findi xs y = xs |> Seq.filter( fun x -> (((x*y) = flip (x*y)) && (separate (x*y) 0 <> 0) ) ) |> Seq.map(fun x -> (x*y,x))
    ys |> Seq.collect(fun y -> (findi xs y)) |> Seq.maxBy(fun t -> fst(t))

findpalindrome [100..999][100..999]

Problem 5

let test = 
    let max = (primes 20 |> Seq.reduce(fun a c -> a*c))*8L*3L
    [1L..20L] |> Seq.filter(fun x -> (max % x) <> 0L)

Problem 6

let diff xs = 
    let sumsq = xs |> Seq.reduce(fun c a -> (a*a)+c)
    let sum = (xs |> Seq.reduce(fun c a -> (a+c)))
    let sqsum  = sum*sum
    sqsum  - sumsq

diff [1..100]

Problem 7

open Microsoft.FSharp.Core.Operators
let primesnth nthprime = 
    let maxPrime = 300000
    let pr : bool array = Array.zeroCreate maxPrime
    let mutable res = 0
    let mutable nth = 0
    let mutable cur=2
    while (nth < nthprime) do
        if not pr.[cur] then
            for wr in cur+cur .. cur .. maxPrime-1 do pr.[wr] <- true
            res <- cur
            nth <- nth + 1 
        cur <- cur + 1
    res

primesnth 10001

Friday, May 28, 2010

Learning F# with projecteuler.net

Wow, lot of fun with projecteuler.net !

Problem 1

[1..999] |> Seq.filter( fun x -> (x % 3 = 0 || x % 5 = 0)) |> Seq.sum

Problem 2

let fib max = 
    let rec fibo a b max = 
        if b>= max then a :: [] else a :: fibo b (a+b) max
    fibo 1 2 max

fib 4000000 |> Seq.filter(fun x -> (x % 2 = 0)) |> Seq.toList|> Seq.sum

Problem 3

open Microsoft.FSharp.Math 
open System.Collections.Generic
let maxPrime:int= (int) (System.Math.Sqrt((float)600851475143I))
let primes maxPrime = 
    let pr : bool array = Array.zeroCreate maxPrime
    let res = new List()
    for cur in 2 .. maxPrime/2 do
        if not pr.[cur] then for wr in cur+cur .. cur .. maxPrime-1 do pr.[wr] <- true
    for cur in 1 .. maxPrime-1 do
        if not pr.[cur] then res.Add(new bigint(cur))
    res

primes maxPrime |> 
    Seq.filter(fun x -> ((600851475143I % x) = 0I )) 
    |> Seq.map( fun x -> ((int)(x))) 
    |> Seq.max

Saturday, April 17, 2010

jni4net NOT yet on Mono & Linux

I started with investigations of support for Mono on x86. The key problem is different calling convention - cdecl. My current implementation of JniLocalHandle is build on top of assumption that small structures are put onto stack same way as scalar types. But that's not valid assumption, it works just for stdcall. cdecl allocates the structure on heap and passes just pointer to the structure, no matter how big the structure is. Why I created JniLocalHandle ? Because I wanted to make strongly typed difference between JniLocalHandle and JniGlobalHandle. We could drop it and use IntPtr in order to deal with this problem. It will impact all generated proxies on C# side.
There is another problem with cdecl, because I need to put
[UnmanagedFunctionPointer(CallingConvention.xxx)]
on any JNI delegate. Example is JNIEnv.AllocObject. I think I'll need to duplicate whole JNIEnv class in order to avoid condition for each call.
Last small problem is with JNI.Dll which has the main
[DllImport("jvm.dll", CallingConvention = CallingConvention.StdCall)]
, it must be duplicated as well, because there is jvm.so on Linux.

Currently I don't hear from people that they need Mono/Linux support for jni4net. If you think you need it, please tell us the use case. I'm interested to hear why Mono support is worth of the effort. Till then I put it on ice.