Git Product home page Git Product logo

frege-repl's Introduction

What is Frege?

Build Status Join the chat at https://gitter.im/Frege/frege Winner of the JavaOne Emerging Languages Bowl 2015, 2016, 2017

Frege is a Haskell for the JVM.

Like any Haskell, it is purely functional, enjoys a strong static type system with global type inference and non-strict - also known as lazy - evaluation.

Frege compiles to Java, runs on the JVM, and uses any Java library you want. It can be used inside any Java project.

A Taste of Frege

1. Hello World

This is the classic starter with a slight extension to show the fluent usage from Java and the benefits of having a type system that can recognize purity.

module Hello where

greeting friend = "Hello, " ++ friend ++ "!"

main args = do
    println (greeting "World")

This code will compile to Hello.class and Hello.java with a regular Java main method that one can start the usual Java way.

Moreover, the Hello.class will have a method

public static String greeting(String ...) {...}

that one can call from Java or any other JVM language.

The greeting function is pure, meaning it is stateless and free of side effects. Therefore, it is threadsafe and its results may be automatically cached since given the same argument, the result will always be the same.

The main function is impure. It takes a list of Strings and does not return just "void" as in most other JVM languages but the type IO (), telling that it may produce side effects like printing to the console. The Frege type system guarantees that any caller of main must also be of some IO type and is thus also marked as impure. That way, the lack of purity percolates up the whole call chain.

"Hello World" already shows the tenet of "islands of purity" (greeting) in a "sea of imperative code" (main).

Since the purity information is carried through the type system, the compiler can potentially use it for many optimizations such as pre-calculation, deferred execution, parallel execution, caching, and elimination of common subexpressions.

Frege is strongly and statically typed, even though we haven't declared any types in the code above. If not declared, the types are inferred. When declared, the given types are checked against the inferred ones.

2. Expressive code

Much can be achieved in Frege in one line of code and here is an example that you can paste into the Online REPL. It calculates pythagorean triples below 10 with the help of a list comprehension:

[ (x,y,z) | x <- [1..10], y <- [x..10], z <- [x..10], x*x + y*y == z*z ]

After execution, you should see a list of triples containing the solutions (3, 4, 5) and (6, 8, 10).

Such a comprehension reads almost like an SQL statement:

  • select the triple (x,y,z)
  • with x drawn from the list of 1 to 10, y from x to 10, and z from x to 10
  • where x*x + y*y == z*z

There are much more elegant and efficient ways to calculate the triples, but those are a bit less obvious.

3. No mutable state

Mutable state is the source of many bugs and makes code less modular. Frege allows interesting ways to avoid it. That style is very unfamiliar to many developers that come from the imperative world. Be brave. It is different but there are a huge benefits to be discovered.

Let's go for a more advanced example where we calculate the fixpoint of the cosine function, i.e. the value where cos(x) == x.

Implementations in imperative languages usually involve introducing local mutable state. Not so in Frege:

import frege.prelude.Math (cos)

cosines = iterate cos 1.0
pairsOf xs = zip xs (tail xs)
head [ x | (x,y) <- pairsOf cosines, x == y] 

After execution, it should show you the value

 0.7390851332151607

The code is most likely incomprehensible for a Frege/Haskell newcomer at first, but it becomes less intimidating once you know the parts. With a bit of experience, you may even find it clear and obvious.

  • Again, we have a list comprehension. We get a list of x values, but we only need the first element, the head.
  • The x comes from an (x,y) pair where x == y.
  • The (x,y) pair is drawn from a list of pairs of cosine values.
  • The cosines are an infinite list of values that starts with 1.0 and then iterates to cos(1.0), cos(cos(1.0)), cos(cos(cos(1.0))), and so forth.
  • Please note that the = signs do not denote an assignment but a definition. There are no assignments in Frege!
  • The pairsOf function works on any list of values to create pairs of any adjacent values. It uses zip, which is an often-used construction for this task, but the details are not relevant here.

This code is pure. The inferred type is Double. The code does not rely on any mutable state (not even internally). Therefore it is threadsafe and the result can be automatically cached.

What's in it for me?

For the Java programmer

Frege offers you the opportunity to learn and use a new programming paradigm that shines with

  • a solid mathematical foundation,
  • pure functions,
  • immutability by default,
  • side-effects only when declared,
  • robustness under composition and concurrency,
  • and a type system that is unparalleled on the JVM with its combination of power, simplicity and expressiveness.

You can still reuse your existing knowledge of the Java platform and its vast set of libraries. Frege interoperates with Java such that you can easily call Frege from Java code and vice versa. But unlike other approaches, calling Java from Frege doesn't undermine the language guarantees.

When calling Java from Frege, you have to declare the Java types in rigid Frege terms in order to preserve the Haskell language characteristics, especially purity, thread safety, and lazy evaluation.

Learning Frege essentially means that you will also learn Haskell and thus your effort pays off twice, since you also get to know a very popular non-JVM language with 25+ years of development, a great community, many (free) books, publications, tutorials, online courses, and considerable industry demand.

For the Haskell programmer

Frege gives you the opportunity to use your skills on the JVM. Most idiomatic Haskell code will run in Frege unmodified or with only minimal, obvious adaptations. Even more important: you can bring your purely functional solution strategies to your Java projects.

From now on you can also enjoy on the JVM:

  • the terse Haskell syntax
  • pure functions and lambdas
  • algebraic data types and typeclasses with parametric polymorphism
  • powerful type inference
  • higher rank types
  • lazy evaluation on infinite data structures
  • pattern matching, list comprehensions, do-notation, point-free style, operators, modules
  • functors, monoids, semigroups, monads, and all your other beloved mathematical abstractions.

Frege aims at compiling most "vanilla" Haskell code that has no external dependencies "as is" or with only minimal, obvious changes. Likewise, Frege code that makes no use of JVM specifics should easily run through other Haskell compilers. We are currently in the progress of coming closer to this goal by ironing out insubstantial differences.

The Name

The Frege programming language is named after and in honor of Gottlob Frege who published the ideas of higher-order functions, partial function application, and many more concepts of formal logic that we now take for granted back in the 19th century.

If you are curious how this name is pronounced, you can use this translator page to get it right. Just click the audio symbol in the left (german) part.

Project State

The compiler, an Eclipse plugin, and a provisional version of the documentation can be downloaded. Note that Frege requires at least JDK 7 to compile and run programs.

A number of tools are written in Frege:

This should speak for itself regarding stability, functional completeness and performance of the language.

The documentation is provisional, and the library supports almost all of the Haskell 2010 standard library with the remaining known differences being there for good reason.

See the Getting Started page for getting started at the command-line or read the Eclipse plugin page. You can develop Frege inside Intellij IDEA with an Intellj IDEA plugin being under active development and there is build automation support for Maven, Gradle, Leiningen, SBT, and Bazel.

The documentation tool and the awesome QuickCheck library for advanced unit testing comes bundled with the language.

Related Projects

Contributions

If you are interested in contributing, here are some hot topics:

  • Write Frege code to support more of the Java API.
  • Port Haskell libraries or tools.
  • Open issues in the issue tracker if you find bugs, errors in documentation, etc.
  • Open issues in the tooling like this one
  • Help make Frege popular by writing code for projects like Rosetta Code, or PLEAC.
  • Contribute to the related projects mentioned above, or make your own.

Contact

Meet Frege friends in person

Talk to us at any of the upcoming events or view historic presentation slides and videos!

For discussions

You can contact the project members through the discussion group devoted to the Frege programming language.

For questions

Specific programming problems are best solved on Stack Overflow, we check questions tagged "frege" on a regular basis.

For casual chat (and quick questions)

There's a #frege channel on Freenode IRC where some project members and Frege users hang out. You can use any IRC client you like or Freenode's WebChat interface if you don't want to install IRC software.

The Frege Gitter channel is also a way tool to connect to the community.

Staying up to date

For issues only

If you find a bug or have an idea for enhancements, please let us know by opening an issue in the issue tracker. (You'll need a GitHub account to do this.) Please keep discussions to the forum and questions to Stack Overflow.

Links

Recommended reading

API Docs

Copyright and License

Copyright (c) Ingo Wechsung, 2011-2022. All rights reserved. The use and distribution terms for this software are covered by the BSD 3-clause license which can be found in the file LICENSE.txt at the root of this distribution. By using this software in any fashion, you are agreeing to be bound by the terms of this license. You must not remove this notice, or any other, from this software.

frege-repl's People

Contributors

bryant1410 avatar ingo60 avatar mmhelloworld avatar mperry avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

frege-repl's Issues

no warnings anymore in repl?

I don't get any warnings anymore, neither in the REPL nor in the online REPL.
And the :set command seems to be without function.
I couldn't alter any settings, be it inline, comments or hints.

Build instructions do not work on a clean system

If you clone the repo to a clean system and run mvn install per the README, it fails on dependency resolution, trying to find frege:frege-interpreter-core:jar:1.0.3-SNAPSHOT.

If there are pre-requisites for building the REPL, the README should list those.

Documentation command

The following would be nice to have:

:help name

(where name could be a qualified name)
which should print the html-ized doc comment for that item.
Most of the needed functionality should already be there in compiler/DocUtils.fr and compiler/EclipseUtils.fr
The only difficulty should be to keep track of the namespaces in scope according to the imports done by the user. This you need to resolve the name and get the corresponding symbol table entry, which could then be handed down to the documentation functions.

Also nice (but not really important) would be to have a command like

:java

to see the generated java code, maybe in an extra tab or page. I sometimes wanted this for answering "how would I write this Haskell code in Java" type questions on stackoverflow quickly. :)

update to new tag line

the tag line in the help window is still "A pure functional programming language for the JVM in the spirit of Haskell."
For the sake of a consistent positioning, we should update to "A Haskell for the JVM".

cheers
Dierk

:t infixl crashes repl

Here's the transcript:

➜  frege  fregerepl
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8
Welcome to Frege 3.21.586-g026e8d7 (Oracle Corporation Java HotSpot(TM) 64-Bit Server VM, 1.8.0_45)

frege> :t infixl 9 `!!`
Not an expression!

frege> :t infixl 9
[ERROR: 4]: unexpected token "infixl" while trying to parse a function or
pattern binding

frege> :t infixl foo
[ERROR: 4]: Illegal precedence `foo´, must be integer from range 1..16

frege> infixl foo
[ERROR: 4]: Illegal precedence `foo´, must be integer from range 1..16

frege> infixl 9 `!!`

frege> :t infixl
Exception in thread "main" frege.runtime.Undefined: tail []
    at frege.prelude.PreludeBase.error(PreludeBase.java:18445)
    at frege.prelude.PreludeList$IListView__lbrack_rbrack.tail(PreludeList.java:2332)
    at frege.compiler.Scanner$1Floop_28130.work(Scanner.java:3224)
    at frege.compiler.Scanner.findInfixImports(Scanner.java:3242)
    at frege.compiler.Scanner$33$1.eval(Scanner.java:3834)
    at frege.compiler.Scanner$33$1.eval(Scanner.java:3831)
    at frege.runtime.Delayed.call(Delayed.java:198)
    at frege.runtime.Delayed.forced(Delayed.java:267)
    at frege.compiler.Scanner.processImports(Scanner.java:2837)
    at frege.compiler.Scanner$33.eval(Scanner.java:3840)
    at frege.compiler.Scanner$33.eval(Scanner.java:3823)
    at frege.runtime.Fun1$1.eval(Fun1.java:62)
    at frege.runtime.Delayed.call(Delayed.java:198)
    at frege.runtime.Delayed.forced(Delayed.java:267)
    at frege.interpreter.FregeInterpreter$11.eval(FregeInterpreter.java:5933)
    at frege.interpreter.FregeInterpreter$11.eval(FregeInterpreter.java:5864)
    at frege.runtime.Fun1$1.eval(Fun1.java:62)
    at frege.runtime.Delayed.call(Delayed.java:198)
    at frege.runtime.Delayed.forced(Delayed.java:267)
    at frege.interpreter.FregeInterpreter$7$1.eval(FregeInterpreter.java:5584)
    at frege.interpreter.FregeInterpreter$7$1.eval(FregeInterpreter.java:5579)
    at frege.runtime.Fun1$1.eval(Fun1.java:62)
    at frege.runtime.Delayed.call(Delayed.java:200)
    at frege.runtime.Delayed.forced(Delayed.java:267)
    at frege.interpreter.FregeInterpreter$24.eval(FregeInterpreter.java:7341)
    at frege.interpreter.FregeInterpreter$24.eval(FregeInterpreter.java:7298)
    at frege.runtime.Fun1$1.eval(Fun1.java:62)
    at frege.runtime.Delayed.call(Delayed.java:198)
    at frege.runtime.Delayed.forced(Delayed.java:267)
    at frege.interpreter.FregeInterpreter$1FcalcSourceType_5816.work(FregeInterpreter.java:7466)
    at frege.interpreter.FregeInterpreter.findSourceType(FregeInterpreter.java:7474)
    at frege.interpreter.FregeInterpreter$IJ$findSourceTypeƒ56008840.eval(FregeInterpreter.java:9091)
    at frege.interpreter.FregeInterpreter$IJ$findSourceTypeƒ56008840.eval(FregeInterpreter.java:9084)
    at frege.runtime.Fun2$2.eval(Fun2.java:77)
    at frege.runtime.Delayed.call(Delayed.java:198)
    at frege.runtime.Delayed.forced(Delayed.java:257)
    at frege.interpreter.FregeInterpreter$IJ$buildScriptƒ5d0e5c8b.eval(FregeInterpreter.java:9134)
    at frege.interpreter.FregeInterpreter$IJ$buildScriptƒ5d0e5c8b.eval(FregeInterpreter.java:9127)
    at frege.runtime.Fun5$2.eval(Fun5.java:77)
    at frege.runtime.Delayed.call(Delayed.java:198)
    at frege.runtime.Delayed.forced(Delayed.java:257)
    at frege.interpreter.FregeInterpreter$11$3.eval(FregeInterpreter.java:5929)
    at frege.interpreter.FregeInterpreter$11$3.eval(FregeInterpreter.java:5927)
    at frege.runtime.Delayed.call(Delayed.java:198)
    at frege.runtime.Delayed.forced(Delayed.java:257)
    at frege.compiler.Scanner$IJ$lexƒ38588a19.eval(Scanner.java:4274)
    at frege.compiler.Scanner$IJ$lexƒ38588a19.eval(Scanner.java:4267)
    at frege.runtime.Fun4$2.eval(Fun4.java:77)
    at frege.runtime.Delayed.call(Delayed.java:198)
    at frege.runtime.Delayed.forced(Delayed.java:257)
    at frege.prelude.PreludeList$IJ$filterƒe0a8f25.eval(PreludeList.java:3531)
    at frege.prelude.PreludeList$IJ$filterƒe0a8f25.eval(PreludeList.java:3524)
    at frege.runtime.Fun2$2.eval(Fun2.java:77)
    at frege.runtime.Delayed.call(Delayed.java:198)
    at frege.runtime.Delayed.forced(Delayed.java:257)
    at frege.compiler.Scanner$IJ$layoutƒf631e324.eval(Scanner.java:4300)
    at frege.compiler.Scanner$IJ$layoutƒf631e324.eval(Scanner.java:4293)
    at frege.runtime.Fun2$2.eval(Fun2.java:77)
    at frege.runtime.Delayed.call(Delayed.java:198)
    at frege.runtime.Delayed.forced(Delayed.java:267)
    at frege.compiler.Scanner$33$1.eval(Scanner.java:3834)
    at frege.compiler.Scanner$33$1.eval(Scanner.java:3831)
    at frege.runtime.Delayed.call(Delayed.java:198)
    at frege.runtime.Delayed.forced(Delayed.java:267)
    at frege.compiler.Scanner.processImports(Scanner.java:2837)
    at frege.compiler.Scanner$33.eval(Scanner.java:3840)
    at frege.compiler.Scanner$33.eval(Scanner.java:3823)
    at frege.runtime.Fun1$1.eval(Fun1.java:62)
    at frege.runtime.Delayed.call(Delayed.java:198)
    at frege.runtime.Delayed.forced(Delayed.java:267)
    at frege.interpreter.FregeInterpreter$11.eval(FregeInterpreter.java:5933)
    at frege.interpreter.FregeInterpreter$11.eval(FregeInterpreter.java:5864)
    at frege.runtime.Fun1$1.eval(Fun1.java:62)
    at frege.runtime.Delayed.call(Delayed.java:198)
    at frege.runtime.Delayed.forced(Delayed.java:267)
    at frege.interpreter.FregeInterpreter$7$1.eval(FregeInterpreter.java:5584)
    at frege.interpreter.FregeInterpreter$7$1.eval(FregeInterpreter.java:5579)
    at frege.runtime.Fun1$1.eval(Fun1.java:62)
    at frege.runtime.Delayed.call(Delayed.java:200)
    at frege.runtime.Delayed.forced(Delayed.java:267)
    at frege.control.monad.State$IMonad_State$3.eval(State.java:1939)
    at frege.control.monad.State$IMonad_State$3.eval(State.java:1936)
    at frege.runtime.Fun1$1.eval(Fun1.java:62)
    at frege.runtime.Delayed.call(Delayed.java:198)
    at frege.runtime.Delayed.forced(Delayed.java:267)
    at frege.interpreter.FregeInterpreter$26.eval(FregeInterpreter.java:7550)
    at frege.interpreter.FregeInterpreter$26.eval(FregeInterpreter.java:7528)
    at frege.runtime.Fun1$1.eval(Fun1.java:62)
    at frege.runtime.Delayed.call(Delayed.java:198)
    at frege.runtime.Delayed.forced(Delayed.java:267)
    at frege.interpreter.FregeInterpreter$27$1.eval(FregeInterpreter.java:7669)
    at frege.interpreter.FregeInterpreter$27$1.eval(FregeInterpreter.java:7633)
    at frege.runtime.Fun1$1.eval(Fun1.java:62)
    at frege.runtime.Delayed.call(Delayed.java:198)
    at frege.runtime.Delayed.forced(Delayed.java:267)
    at frege.interpreter.FregeInterpreter$IMonad_Interpreter$3.eval(FregeInterpreter.java:4723)
    at frege.interpreter.FregeInterpreter$IMonad_Interpreter$3.eval(FregeInterpreter.java:4719)
    at frege.runtime.Fun1$1.eval(Fun1.java:62)
    at frege.runtime.Delayed.call(Delayed.java:198)
    at frege.runtime.Delayed.forced(Delayed.java:267)
    at frege.control.arrow.Kleisli$IMonad_Kleisli$1Fgo_23179$1.eval(Kleisli.java:1182)
    at frege.runtime.Fun1$1.eval(Fun1.java:62)
    at frege.runtime.Delayed.call(Delayed.java:198)
    at frege.runtime.Delayed.forced(Delayed.java:267)
    at frege.control.monad.State$IMonad_State$4.eval(State.java:1960)
    at frege.control.monad.State$IMonad_State$4.eval(State.java:1953)
    at frege.runtime.Fun1$1.eval(Fun1.java:62)
    at frege.runtime.Delayed.call(Delayed.java:200)
    at frege.runtime.Delayed.forced(Delayed.java:267)
    at frege.control.monad.State$IMonad_State$4.eval(State.java:1956)
    at frege.control.monad.State$IMonad_State$4.eval(State.java:1953)
    at frege.runtime.Fun1$1.eval(Fun1.java:62)
    at frege.runtime.Delayed.call(Delayed.java:198)
    at frege.runtime.Delayed.forced(Delayed.java:267)
    at frege.interpreter.FregeInterpreter$TInterpreter.run(FregeInterpreter.java:3965)
    at frege.repl.FregeRepl$21$1.eval(FregeRepl.java:5857)
    at frege.runtime.Delayed.call(Delayed.java:198)
    at frege.runtime.Delayed.forced(Delayed.java:257)
    at frege.repl.FregeRepl$IMonad_Repl._return(FregeRepl.java:4515)
    at frege.repl.FregeRepl$21.eval(FregeRepl.java:5846)
    at frege.repl.FregeRepl$21.eval(FregeRepl.java:5844)
    at frege.runtime.Fun1$1.eval(Fun1.java:62)
    at frege.runtime.Delayed.call(Delayed.java:198)
    at frege.runtime.Delayed.forced(Delayed.java:267)
    at frege.repl.FregeRepl$IMonad_Repl$3.eval(FregeRepl.java:4477)
    at frege.repl.FregeRepl$IMonad_Repl$3.eval(FregeRepl.java:4468)
    at frege.runtime.Fun1$1.eval(Fun1.java:62)
    at frege.runtime.Delayed.call(Delayed.java:198)
    at frege.runtime.Delayed.forced(Delayed.java:267)
    at frege.repl.FregeRepl$TRepl.run(FregeRepl.java:3557)
    at frege.repl.FregeRepl$40.eval(FregeRepl.java:6619)
    at frege.runtime.Fun1$1.eval(Fun1.java:62)
    at frege.runtime.Delayed.call(Delayed.java:200)
    at frege.runtime.Delayed.forced(Delayed.java:257)
    at frege.repl.FregeRepl$41.eval(FregeRepl.java:6691)
    at frege.runtime.Fun1$1.eval(Fun1.java:62)
    at frege.runtime.Delayed.call(Delayed.java:198)
    at frege.runtime.Runtime.runMain(Runtime.java:225)
    at frege.repl.FregeRepl.main(FregeRepl.java:7414)
➜  frege

earlier hints and warnings are repeated

I think this was not so in previous versions:

Welcome to Frege 3.22.367-g2737683 (Oracle Corporation OpenJDK Server VM, 1.8.0_40-internal)

frege> import Data.Monoid
[HINT: 3]: H <console>.fr:3: unused import of Data.Monoid as Monoid

frege> 5 == true
[ERROR: 4]: E <console>.fr:4: Bool is not an instance of Num
[HINT: 2]: H <console>.fr:2: unused import of Data.Monoid as Monoid

frege> 5 == 4
false

frege> true == "why?"
[ERROR: 4]: E <console>.fr:4: type error in  expression "why?"
    type is   String
    used as   Bool
[HINT: 2]: H <console>.fr:2: unused import of Data.Monoid as Monoid

The same happens with other warnings and hints.

frege-repl-1.4-SNAPSHOT.zip checksum changed

When frege-repl was added to Homebrew in May 2016, the sha256 for frege-repl-1.4-SNAPSHOT.zip was 2cf1c2a8f7b64c9d70b21fbfd25b2af3f5e3bebe3662f724afd435d01bddafec, but seems to be 2ca5f13bc5efaf8515381e8cdf99b4d4017264a462a30366a873cb54cc4f4640 now, which means the Homebrew installation fails with

Error: SHA256 mismatch
Expected: 2cf1c2a8f7b64c9d70b21fbfd25b2af3f5e3bebe3662f724afd435d01bddafec
Actual: 2ca5f13bc5efaf8515381e8cdf99b4d4017264a462a30366a873cb54cc4f4640

I suppose this is due to the snapshot being updated in place after the addition to Homebrew. Can you confirm this and the correctness of the checksum?

Trouble with infix operators

Here is todays session:

ingo@ibinti:~/Frege/frege$ repl
Welcome to Frege 3.21.586-g026e8d7 (Oracle Corporation OpenJDK Server VM, 1.7.0_65)

frege> (x³) = x^3   -- gives a reasonable answer
[ERROR: 3]: unexpected '³' while trying to parse unary expression

frege> infix 1 `³`    -- oops, forgot the infix

frege> (x³) = x^3   -- yay! now it works
function ³ :: Num α => α -> α

frege> (3³)         -- what is 3 cubed?
[ERROR: 4]: unexpected '}' while trying to parse left hand side of a
function or pattern binding
[ERROR: 4]: syntax error on end of file

frege> id (3³)      -- avoid ( at beginning  
[ERROR: 4]: unexpected '}' while trying to parse left hand side of a
function or pattern binding
[ERROR: 4]: syntax error on end of file

frege> map (³) [1..10]  
[ERROR: 4]: unexpected '}' while trying to parse left hand side of a
function or pattern binding
[ERROR: 4]: syntax error on end of file

frege> map (`³`) [1..10]     -- works, but ...
[1,8,27,64,125,216,343,512,729,1000]

Turns out the repl doesn't like the new operator at all - except, for what reason ever, when defining (x³)
If I reuse a prelude operator, like ~ this all does work fine.

Note: operator recognition and parsing will be different from 3.22.xxx on, so if this is not a simple fix, just let it be how it is.

let gradle (or travis?) obtain recent frege.jar version from github

Since apparently no one feels responsible anymore for putting recent frege releases to Maven, and since this is also apparently not possible or desirable to do in an automated fashion, I propose the following for frege-repl and frege-interpreter alike:

Let gradlew check some relative path (i.e. lib/frege3.24-latest.jar) for a frege jar to work with, and fetch it from github if not present. It'd certainly be best to use the same one in the repl as in the interpreter, of course.

This way, we would not have to rely on Maven. There could be one and only one place where the jar to download would be specified. (This would be documented in the README.md, of course.) And people needing a most recent frege jar or even one that is just in development could use the repl with that one as well.

Support installation via Homebrew

Homebrew is "The missing package manager for OS X". It is very popular because it allows for easy/versioned installations.

It would be great to have a package (aka formula) for the frege-repl – any plans?

I have never written a homebrew package before, but it looks quite simple and I would happily give it a shot if you are interested.

REPL immediately exits

frege-repl [master] $ ./gradlew --console plain :frege-repl-core:run
:frege-repl-nativedeps:compileFrege UP-TO-DATE
:frege-repl-nativedeps:compileJava UP-TO-DATE
:frege-repl-nativedeps:compileGroovy UP-TO-DATE
:frege-repl-nativedeps:processResources UP-TO-DATE
:frege-repl-nativedeps:classes UP-TO-DATE
:frege-repl-nativedeps:jar UP-TO-DATE
:frege-repl-core:compileJava UP-TO-DATE
:frege-repl-core:compileFrege UP-TO-DATE
:frege-repl-core:compileGroovy UP-TO-DATE
:frege-repl-core:processResources UP-TO-DATE
:frege-repl-core:classes UP-TO-DATE
:frege-repl-core:run
Welcome to Frege 3.22.524-gcc99d7e (Oracle Corporation Java HotSpot(TM) 64-Bit Server VM, 1.8.0_45)

frege>
BUILD SUCCESSFUL

Total time: 3.514 secs

This build could be faster, please consider using the Gradle Daemon: http://gradle.org/docs/2.5/userguide/gradle_daemon.html
frege-repl [master] $

I return to bash immediately. Am I doing something incorrectly?

Unrelated, I think the instructions under How to run? are out of date, as the zip file I found did not contain binaries.

generated fregei script does not work

After

./gradlew install

I try to run the fregei script, but it fails to find the main class.

Error: Could not find or load main class frege.repl.FregeRepl 

It generates the following command-line to execute:

java -classpath /home/ingo/Frege/frege-repl/frege-repl-core/build/lib/frege-repl-core-1.2.1-SNAPSHOT.jar:...

but there is no directory build/lib, only build/libs

But even if I make a symbolic link from lib to libs, it still doesn't run. The build/libs directory contains only:

ingo@freguntu:~/Frege/frege-repl$ ls -l frege-repl-core/build/libs
total 540
-rw-rw-r-- 1 ingo ingo 543981 Okt 31 11:16 frege-repl-core-1.2.1-SNAPSHOT.jar
-rw-rw-r-- 1 ingo ingo    261 Okt 31 11:16 frege-repl-core-1.2.1-SNAPSHOT-javadoc.jar
-rw-rw-r-- 1 ingo ingo    639 Okt 31 11:16 frege-repl-core-1.2.1-SNAPSHOT-sources.jar

but the generated command expects many more, like jline.jar, ecc.jar

Note that I can run

./gradlew -q run

Not to offend anyone, but I really hate it to run everything through gradle. A build tool should build something I can run without the build tool, right?

(I did this to give the REPL more stack size. I have no idea how to tell ./gradle to do this.)

Please handle end-of-file gracefully

Example session, at prompt enter CTRL-D:

ingo@ibinti:~/repl$ java -jar frege-repl-1.0.3-SNAPSHOT.jar -warn -hints
Welcome to Frege 3.21.500-g88270a0 (Oracle Corporation OpenJDK Server VM, 1.7.0_51)

frege> Exception in thread "main" java.lang.NullPointerException
at frege.repl.FregeRepl$TCommand$M.parse(FregeRepl.java:3092)
at frege.repl.FregeRepl$17.eval(FregeRepl.java:5309)
at frege.repl.FregeRepl$17.eval(FregeRepl.java:5243)
at frege.runtime.Fun1$1.eval(Fun1.java:62)
at frege.runtime.Delayed.call(Delayed.java:198)
at frege.runtime.Delayed.forced(Delayed.java:267)
at frege.repl.FregeRepl$40.eval(FregeRepl.java:6390)
at frege.runtime.Fun1$1.eval(Fun1.java:62)
at frege.runtime.Delayed.call(Delayed.java:198)
at frege.runtime.Delayed.forced(Delayed.java:257)
at frege.repl.FregeRepl$41.eval(FregeRepl.java:6459)
at frege.runtime.Fun1$1.eval(Fun1.java:62)
at frege.runtime.Delayed.call(Delayed.java:198)
at frege.runtime.Runtime.runMain(Runtime.java:225)
at frege.repl.FregeRepl.main(FregeRepl.java:7182)

SNAPSHOT-1.2.0 commands not working

The following does not work:

import Test.QuickCheck
:browse QuickCheck

It doesn't show anything. If I do

x = sample
:browse

still nothing!

Also

:help 
At the prompt, you can enter Frege code snippets to get them evaluated.^JThe output or compilation errors ...

prints a long line with ^J instead of newlines. However, println "a\nb" prints the lines correctly.

Make ReplIO control the javaSource and helpGUI

In the JavaFX version of the repl, I have to display GUIs for the javaSource and the help differently from other repls, namely in JavaFX controls. ATM this means that I have to duplicate pretty much all of the repl-core code. But I could reuse the code much more easily, if the ReplUI class demanded functions to open the help or java view.

The code under
https://github.com/Frege/frege-repl/blob/master/frege-repl-core/src/main/frege/frege/repl/FregeRepl.fr#L115-L117
would then use the ReplUI.showJavaView / helpView function provided by the ReplIO.

Would it be ok to do such a change?

Difference in behavior with inline and multi-line definition with type annotation

frege> type F = (forall b. [b] -> [b]) -> Int
type alias F :: ?

frege> g :: F -> Int; g f = undefined
4: application of g will diverge.
4: Type [b]->[b]
inferred from  g is not as polymorphic as
expected type  forall b.[b] -> [b]

frege> :{
> g :: F -> Int
> g f = undefined
> :}
function g :: ((forall b.[b] -> [b]) -> Int) -> Int

Top level definition fails when it shouldn't

See the transcript:

ingo@obonto:~$ repl
Welcome to Frege 3.21.586-g026e8d7 (Oracle Corporation Java HotSpot(TM) 64-Bit Server VM, 1.7.0_51)

frege> :{
test :: Num a => a -> String
test 2 = "two"
:}

function test :: Num a => a -> String
[WARNING: 4]: guard (fromInt 2 `Eq.==` 2) may evaluate to false.

Fine, so far.

frege> but :: Num a => a -> String; but 2 = "two"
[ERROR: 5]: type `Int` is not as polymorphic as suggested in the annotation where just `a` is announced.
[HINT: 5]: The inferred type must be at least as polymorphic as the annotated one.
[ERROR: 5]: type error in  expression but type is   a used as   Int

This is exactly the same, just given in one line. Why is it treated differently?

And the following is also ok:

frege> let but :: Num a => a -> String; but 2 = "two" in but 2.0
two

Error when evaluating an expression after importing a Frege source that includes module or package declaration

Hi everyone !

Here's the file

module Toto where

toto = 1

then start a REPL session:

[yoeight@gikoo frege-repl-1.0-20131203.0006]$ java -jar frege-repl-1.0.jar 
Welcome to Frege 3.21.107-g4bd09eb (Oracle Corporation OpenJDK 64-Bit Server VM, 1.7.0_15)

frege> :l /home/yoeight/Desktop/Toto.fr

frege> {any valid expression}
8: syntax error on end of file
8: unexpected '}' while trying to parse left hand side of a
function or pattern binding
3: illegal left hand side of a function definition: Toto
3: unexpected token "where" while trying to parse left hand side of
a function or pattern binding
3: unexpected token "module" while trying to parse a package

My setup:

OS
3.7.10-1-ARCH

Java

java version "1.7.0_15"
OpenJDK Runtime Environment (IcedTea7 2.3.7) (ArchLinux build 7.u13_2.3.7-2-x86_64)
OpenJDK 64-Bit Server VM (build 23.7-b01, mixed mode)

Frege
3.21.107-g4bd09eb

REPL
1.0-20131203.0006

Note that I also experienced that issue with the previous version of the REPL

Regards

REPL does not read version from fregec.jar?

I just downloaded Frege REPL 1.2.1-SNAPSHOT, and changed the fregei shell script so that it uses frege3.22.525-g704b834.jar.

However, the version displayed is still 424:

ingo@freguntu:/tmp$ frepl  # just alias to fregei
/home/ingo/bin/java
Welcome to Frege 3.22.524-gcc99d7e (Oracle Corporation Java HotSpot(TM) 64-Bit Server VM, 1.8.0_40)

frege> :version
3.22.524-gcc99d7e

frege> 10-2*3
4

But because it outputs the correct result from the expression (instead 24) means that it actually uses the 525 jar.

I think it would be better to report the actual version from frege.Version. For, when we get a bug report, it'll be hard to establish which frege jar is actually used otherwise.

distinguish program arguments from system properties

ATM, program arguments like terminal=gui appear in the syntax of system properties (-Dterminal=gui) but cannot be set as system arguments. They must be set in the place where program arguments appear - but in the syntax of system arguments. That is surprising.

I'd suggest to make it a usual program argument.

Command Line REPL doesn't like simple module names?

Here is a transcript:

frege> :load /home/ingo/frege/examples/CommandLineClock.fr
Module examples.CommandLineClock
frege> :browse examples.CommandLineClock
data type Date :: native java.util.Date
value current :: IO String
value main :: [String] -> IO ()
frege> current
[ERROR: 4]: can't resolve `current`, did you mean `curry` perhaps?
frege> import examples.CommandLineClock
frege> current
"Mon Oct 27 21:12:35 CET 2014"

So far, so good.
But then:

frege> :load /home/ingo/frege/frege/Scrap.fr
Module Scrap
frege> :browse Scrap
function toDouble :: Integral a => a -> Double
value foo :: [Double]
frege> import Scrap
frege> foo
[ERROR: 1]: The import Scrap cannot be resolved

To reproduce, try to load and import a module with a simple name, and then use definitions from it.

Integrate repl in frege.jar?

I see that there are no external dependencies anymore in frege-repl and frege-interpreter, the only exception being jline. Since the 1.8 frege.jar is only 7.5MB, I think it would be possible and useful to ship the frege.jar with the repl included.

I have no idea what the status of the (elder) jline packages is. Is there any obstacle in shipping them in an uber-jar that contains compiler, repl, library, documentation, quickcheck and doc tool in 8MB?

Recognize -comments and -O/-inline options.

I use the REPL often to check the code generated for some silly expressions. However, the REPL produces only uncommented, un-optimized code.

It would be great if we could give the -comments and -inline options on the command line.

Even better would be to have a :set command for switching various flags on and off. (Of course, crucial flags like -j, -make and so on should not be settable).

Load files from directory

It is difficult to load a script with all its dependencies. Please, add the posiblility to load not the file, but all the files in the directory.

First official release

The frege repl has not had an official release, the current version is 1.1.1-SNAPSHOT. Should this be released as 1.1 and any further changes done to a 1.2-SNAPSHOT version?

Frege-repl-core with Frege version 3.22.524?

for the javafx repl I tried use frege-repl-core with frege version 3.22.524-gcc99d7e but got the error below.

Any plans to upgrade the frege version?

cheers
Dierk

Exception in thread "main" java.lang.NoSuchMethodError: frege.compiler.types.Global$TOptions.mk(Ljava/lang/String;Lfrege/prelude/PreludeBase$TList;JLjava/lang/String;Lfrege/prelude/PreludeBase$TList;Ljava/lang/String;Lfrege/prelude/PreludeBase$TMaybe;Lfrege/prelude/PreludeBase$TList;)Lfrege/compiler/types/Global$TOptions;
at frege.interpreter.FregeInterpreter.createopts(FregeInterpreter.java:6830)
at frege.interpreter.FregeInterpreter$26$1.eval(FregeInterpreter.java:6851)

Print type for non `show`able values

Currently in Frege REPL,

frege> []
7: Ambiguous type Show α => String in value `res2`

frege> Just (\x -> x)
1: t3410->t3410 is not an instance of Show

If a snippet compiles but fails during the REPL's implicit application of show, REPL should print the type instead of throwing the error.

compatibility with newer versions of the compiler

It appears that release 1.3 fails to start with frege org.frege-lang:frege:3.23.422-ga05a487

Exception in thread "main" java.lang.NoSuchMethodError: frege.prelude.PreludeBase$TStringJ._plus_plus(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
at frege.repl.FregeRepl.(FregeRepl.java:6543)

event expansion vs. tab expansion

It looks like the jline repl does "event expansion":

frege> !true
[ERROR] Could not expand event
java.lang.IllegalArgumentException: !true: event not found
at jline.console.ConsoleReader.expandEvents(ConsoleReader.java:849)
at jline.console.ConsoleReader.finishBuffer(ConsoleReader.java:700)
at jline.console.ConsoleReader.accept(ConsoleReader.java:2010)
at jline.console.ConsoleReader.readLine(ConsoleReader.java:2691)
at jline.console.ConsoleReader.readLine(ConsoleReader.java:2372)
at jline.console.ConsoleReader.readLine(ConsoleReader.java:2360)
    ....

This is unfortunate, as we have to escape every occurence of ! with a backslash.
Is it possible to turn this off?

On a related note, what would be great to have would be tab expansion.
I am sure there are some predefined tab-handlers that take a list of items or some such, and that list could easily be constructed from the base names of all known symbols, plus the known module names.

Amount of output

List output is truncated, which is a good thing in case someone tries to print an infinite list.

frege> iterate (*2) 3.14
[3.14,6.28,12.56,25.12,50.24,100.48,200.96,401.92,803.84,1607.68,3215.36,6430.72

However, it is not transparent what the limit is (characters? list elements?) and, above all, it is not configurable. Hence I propose something like:

:set listmax 30

which would make the REPL print 30 list elements.

I understand it is hard, because there may be a finite list or something that has infinite sublists. But this seems to fail also today, try

frege> Just $ iterate (*3) 3.14

Perhaps a character limit is in order, to make things not too complex. But also this limit should be configurable.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.