Using Lisp in C#

2019-02-08 17:50发布

As a lot of people pointed out in this question, Lisp is mostly used as a learning experience. Nevertheless, it would be great if I could somehow use my Lisp algorithms and combine them with my C# programs. In college my profs never could tell me how to use my Lisp routines in a program (no, not writing a GUI in Lisp, thank you). So how can I?

标签: c# lisp
7条回答
▲ chillily
2楼-- · 2019-02-08 18:16

Clojure is a Lisp-1 that is compiled on-the-fly to Java bytecode, leading to very good runtime performance. You can use Clojure, and cross-compile it to a .NET assembly using IKVM's ikvmc. Of course, when used in .NET, Clojure happily generates .NET IL, leading to the same kind of compiled-code performance you can expect when using it on a JVM.

查看更多
Fickle 薄情
3楼-- · 2019-02-08 18:16

If it's merely the routines you want to use you might try LSharp, which lets you have Lisp expressions in .NET:

http://www.lsharp.org/

The other way around (using .NET from Lisp) would be RDNZL:

http://www.weitz.de/rdnzl/

查看更多
家丑人穷心不美
4楼-- · 2019-02-08 18:16

The .Net 1.1 SDK contains a LISP compiler example. See SDK\v1.1\Tool Developers Guide\Samples\clisp

查看更多
乱世女痞
5楼-- · 2019-02-08 18:16

I know this is a really old question. But I'll try to provide an answer from my own experience and perspective.

To those like us who love the pureness and elegance and simplicity of Scheme/Lisp, I hope this gives you some encouragement and inspiration how they can be very useful in real production :)

I recently open-sourced a Scheme-like interpreter from work called schemy, written in C# (~1500 line of code). And here's the motivation and how it is useful -

Without going into too much detail, I was building a web API server, whose request handling logic is desired to be plug-and-play by other developers/data scientists. There was a clear demand for separation of concern here - the server does not care much about the request handling logic, but it needs to know which requests it can handle and where to find and load the logic for the handlers.

So instead of putting handlers implementation in the server application, the server only provides re-usable "blocks" that can be chained together based on some criteria and logic to form a pipeline, i.e., handlers defined via configuration. We tried JSON/XML to describe such a pipeline and quickly realized that I was essentially building an abstract syntax tree parser.

This was when I realized this was a demand for a lightweight, s-expression based small language. Hence I implemented the embeddable schemy interpreter.

I put an example command handling application here, which captures the essence of the design philosophy for the web server I mentioned above. It works like so:

  1. It extends an embedded Schemy interpreter with some functions implemented in C#.

  2. It finds .ss scripts which defines a command processing pipeline by using those implemented functions.

  3. The server finds and persists the composes pipeline from a script by looking for the symbol EXECUTE which should be of type Func<object, object>.

  4. When a command request comes in, it simply invokes the corresponding command processor (the one defined by EXECUTE), and responses with the result.

Finally, here's a complex example script, that provides an online man-page lookup via this TCP command server:

; This script will be load by the server as command `man`. The command
; is consistent of the following functions chained together:
;
; 1.  An online man-page look up - it detects the current operating system and 
;     decides to use either a linux or freebsd man page web API for the look up.
; 
; 2.  A string truncator `truncate-string` - it truncates the input string, in
;     this case the output of the man-page lookup, to the specified number of
;     characters.
; 
; The client of the command server connects via raw RCP protocol, and can issue
; commands like:
; 
;     man ls
; 
; and gets response of the truncated corresponding online manpage content.

(define EXECUTE
  (let ((os (get-current-os))
        (max-length 500))
    (chain                                      ; chain functions together
      (cond                                     ; pick a manpage lookup based on OS
        ((equal? os "freebsd") (man-freebsd))
        ((equal? os "linux") (man-linux))
        (else (man-freebsd)))
      (truncate-string max-length))))           ; truncate output string to a max length

With this script loaded by the command server, a TCP client can issue commands man <unix_command> to the server:

$ ncat 127.0.0.1 8080

man ls

LS(1)                   FreeBSD General Commands Manual                  LS(1)

NAME
     ls -- list directory contents

SYNOPSIS
     ls [--libxo] [-ABCFGHILPRSTUWZabcdfghiklmnopqrstuwxy1,] [-D format]
        [file ...]

DESCRIPTION
     For each operand that names a file of a type other than directory, ls
     displays its name as well as any requested, associated information.  For
     each operand that names a file of type directory, ls displays the names
     of files contained within that directory, as well as any requested,
查看更多
兄弟一词,经得起流年.
6楼-- · 2019-02-08 18:29

Try these .Net implementations of Lisp:

IronScheme will aim to be a R6RS conforming Scheme implementation based on the Microsoft DLR.

L Sharp .NET is a powerful Lisp-like scripting language for .NET. It uses a Lisp dialect similar to Arc but tightly integrates with the .NET Framework which provides a rich set of libraries.

查看更多
爷、活的狠高调
7楼-- · 2019-02-08 18:31

There is also DotLisp.

查看更多
登录 后发表回答