Giter Site home page Giter Site logo

purescript-python / purescript-python Goto Github PK

View Code? Open in Web Editor NEW
119.0 13.0 3.0 264 KB

A Python backend for PureScript.

License: MIT License

Haskell 26.16% Python 1.75% Shell 0.26% Dhall 2.07% JavaScript 0.15% PureScript 69.61%
purescript python compiler

purescript-python's Introduction

PureScript to Python Compiler

Build Status gitter room install py interop

Get Started

  1. *Install a CPython distribution.

    If you're already a user of CPython, you can skip this step.

    Otherwise, go to this official download page, download and install any valid distribution(>=3.5, <=3.8).

  2. Install nodejs, which is distributed with a command npm, and use npm to install purescript and its package manager spago. The latest version of the purescript compiler that is supported is 0.13.8:

    npm install -g purescript
    npm install -g spago

    You might check PureScript: Getting Started for more details.

  3. Install PureScript-Python components:

    curl -fsSL https://raw.githubusercontent.com/purescript-python/installer/master/install.sh | bash

  4. Create an empty folder called hello-world somewhere appropriate,get in, and call

    spago init  # init purescript project
    pspy --init # init purescript-python local configuration
    
  5. Add a key backend with value "pspy", to file spago.dhall of your hello-world project. This is an example:

     {-
     Welcome to a Spago project!
     You can edit this file as you like.
     -}
     { name = "my-project"
     , dependencies = [ "console", "effect", "psci-support" ]
     , packages = ./packages.dhall
     , sources = [ "src/**/*.purs", "test/**/*.purs" ]
     , backend = "pspy" -- !!NOTE THIS!!
     }
  6. Write your code in src/**.purs, and use spago run to execute your project(the default entry module is Main).

PureScript Learning Materials

PureScript is close to Haskell, hence a Haskell user can pick it up in few seconds.

The home of PureScript is PureScript.org, where you can find things involving documentations.

HOW-TO: IDE Support

A major motivation for my working on PureScript is its lightweighted but awesome IDE support.

For VSCode users, installing the plugin PureScript IDE and File -> Preferences -> Settings -> (search purescript) -> Turn on "Add Spago sources" will be sufficient. No need to install some GitHub repo and build for 4 hours! And this IDE feels swift!

Troubleshoot pspy-blueprint

If pspy-blueprint provided by the Python package purescripto didn't work(e.g., users of MacOSX < 10.15), you should manually install it from this repository, and currently there're 2 options:

  1. Install from GitHub release page.
  2. Install from source(Need Haskell stack): clone this repo, and use command stack install ., which will install pspy-blueprint to your .local PATH.

For Linux users, you might also need to use chmod u+x <path/to/pspy-blueprint> to allow the permission to execute.

Troubleshoot: Execution Not Sync to Latest Code

This seems to be a recent issue produced by the upstream compiler, and you can resolve this by removing the current output directory:

rm -rf $YOUR_PROJECT_ROOT/output && spago build && pspy --run

This will produce the result of your latest code.

purescript-python's People

Contributors

akazukin5151 avatar hong-xiang avatar lfkdsk avatar thautwarm 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  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

purescript-python's Issues

Troubleshoot: Execution Not Sync to Latest Code

This slows down compilation considerably.

I would be glad to help, but I don't want to duplicate effort. Do you know what is the exact cause of this problem? Does it have an upstream issue report?

Nix-based installer

Hey folks, this is an awesome project you've created! I think it would be great to have a way of building and installing this via Nix as well.

Python FFI file import error

  File "C:\Users\twshe\Desktop\tutorials\hello-bili\.spago\effect\v2.0.1\src\Effect.purs", line 1, in hello_bili.Effect.pure
    -- | This module provides the `Effect` type, which is used to represent
KeyError: 'bindE'

This is because in such a python package,

- Effect/
    - ...
- Effect.py

The module Effect.py will be ignored.

Code is generated on "spago run" (expected that to happen on "spago build")

In this sample "hello world" project: https://github.com/fornwall/purescript-python-example

We can see that running spago run leads to a lot of output about codegen, such as (from the Run the python docker image section of https://github.com/fornwall/purescript-python-example/runs/914247539?check_suite_focus=true):

Codegen Python for Main
Codegen Python for Effect
Codegen Python for Control.Applicative
Codegen Python for Control.Apply
[...]

This slows down running multiple times considerably, as each run means generating code, and I would expect the code generation to take place when running spago build instead.

Is there a way to move code generation to build time? Here is the Dockerfile with the steps: https://github.com/fornwall/purescript-python-example/blob/master/Dockerfile.python

FFI providers for some essential purescript libraries

Implemented examples see https://github.com/purescript-python/purescript-*.py.

WIP:
The remaining FFI works to support things like Data.Map from ordered-collections:

CONTRIBUTING

Some notes for making a FFI provider repo of purescript-python:

  1. if {} in *.js is used for representing purescript's Unit, we use None as a correspondence for Python FFI.
  2. Note a.value in JS is always a["value"] in Python.
  3. JavaScript functions do not check the argument number by default, hence, sometimes, the purescript developers usually use f() to invoke a purescript function f with argument Unit. So please be careful if you're working with functions with zero/one arguments, especially for the monad-related libraries.

Implementing FFI for external packages

Hi,

Thanks so much for making this! It's a great idea and I'm looking forward to following the evolution of the project.

I was wondering how one could implement a python FFI for dependency packages. For example, if I want to use https://github.com/purescript/purescript-quickcheck, that package has a file Gen.purs that makes use of Gen.js via the FFI. If I wanted to use this package on the python side, would there be a way to do a polyfill of Gen.js (ir a Gen.py) without forking the repo? The same goes for all the dependencies of that project (there are many) that would also need FFI polyfills in python.

Thanks!

Trying to run a helloworld program, get "Backend "pspy" exited with error:2"

I have installed pspy (with all the dependencies like pspy-blueprint) and wanted to try building a simple hello-world program. However when I execute

spago run

I get (after lots of happy compiling) the error:

pspy: error: unrecognized arguments: Main.main
[error] Running failed; Backend "pspy" exited with error:2

Why's that? And how can I fix this?

Details

My helloworld program is in src/Main.purs:

module Main where

import Prelude

import Effect (Effect)
import Effect.Console (log)

main :: Effect Unit
main = do
  log "Hello World"

I have initialized the project with

spago init
pspy --init

and added the pspy backend to spago.dhall.

Could have other/original licence

It's now under GNU LESSER GENERAL PUBLIC LICENSE.

There're some reasons for why I have to choose this

This is the license of the compiler itself, and I just note you can choose any license for it, even if you would link statically to LGPL (but not for GPL, that's the point of the lesser/library GPL).

For the code you emit, there's the https://en.wikipedia.org/wiki/GPL_linking_exception for linking to GPL (but not needed for LGPL).

So if you really didn't want this license (I'm not saying it's bad), then you may have limited time to go back. I only noticed two commits since from others, and one was trivial, so I think can be ignored, and the other maybe, and even if it isn't it's only for tests and they could keep LGPL (or you could ask that person).

Optimizations to avoid python recursion limit

For programs with deep monadic stacks used to traverse recursive structures, the python recursion limit is often hit. Setting a higher recursion limit via sys.setrecursionlimit fixes the problem most of the time, but even with very high recursion limits the issue still appears sometimes.

Are there any optimizations that can be done on the code-gen level to help with this? Ie turning tail recursion into loops, creating functions that take multiple arguments to get rid of currying when possible, etc. I'm not sure what's possible, but it'd be nice to keep a running list here and see if we can tackle any of them.

Documenting how to construct algebraic datatypes from python

For interop, I'm having trouble calling a purescript function from python. If I have:

just :: Int -> Maybe Int
just = Just

addMaybe :: Maybe Int -> Maybe Int -> Maybe Int
addMaybe a b = (+) <$> a <*> b

Then this works:

import foo.Main.pure as Main
print(Main.addMaybe(Main.just(1))(Main.just(2)))

This produces the wrong output (it yields nothing):

import foo.Main.pure as Main
import foo.Data.Maybe.pure as Maybe
Just = Maybe.Just
print(Main.addMaybe({'value0': 3, '.t': Just})({'value0': 3, '.t': Just}))

and this crashes.

import foo.Main.pure as Main
import foo.Data.Maybe.pure as Maybe
Just = Maybe.Just
print(Main.addMaybe(Just(1))(Just(2)))

The first solution is of course fine, but it requires more boilerplate, and I'm assuming it must be possible to use the Just constructor or the Nothing constructor directly somehow.

Thanks!

spago run does codegen

It looks like spago run does codegen in addition to spago build. For production apps, when startup time is important, this has a negative impact. Would it be possible to limit the codegen to only spago build?

Build on MacOS

ghc-options: -Wall -O2 -static
cc-options: -static
ld-options:
- -static
- -pthread

Remove all -static options above.

It seems that MacOS does not support statically linked executables.

purescript/maybe segfaults at runtime

Is there another package for the Maybe monad that purescript-python supports? In normal purescript, I run spago install maybe to use the Maybe monad. However, if I try to do that with purescript-python, it compiles but segfaults at runtime.

module Main where

import Prelude

import Effect (Effect)
import Effect.Console (log)

import Data.Maybe

x :: Maybe Int
x = Just 2

y :: Maybe Int
y = Nothing

main :: Effect Unit
main = do
  log "๐Ÿ"
  -- Doesn't matter which 3 branches are commented, all segfaults
  --log $ show x
  --log $ show y
  case x of
    Just i -> log $ show i
    Nothing -> log "nothing"

Steps to reproduce

git clone https://github.com/purescript-python/example-hw
cd example-hw
# See [1]
spago upgrade-set
# See [2]
spago install prelude
spago install maybe
# Edit src/Main.purs as above
spago build && pspy --run

The output

Compiling Main
Warning 1 of 2:

  in module Main
  at src/Main.purs:8:1 - 8:18 (line 8, column 1 - line 8, column 18)

    Module Data.Maybe has unspecified imports, consider using the explicit form:

      import Data.Maybe (Maybe(..))



  See https://github.com/purescript/documentation/blob/master/errors/ImplicitImport.md for more information,
  or to contribute content related to this warning.

Warning 2 of 2:

  in module Main
  at src/Main.purs:3:1 - 3:15 (line 3, column 1 - line 3, column 15)

    Module Prelude has unspecified imports, consider using the explicit form:

      import Prelude (Unit, discard, show, ($))



  See https://github.com/purescript/documentation/blob/master/errors/ImplicitImport.md for more information,
  or to contribute content related to this warning.


[info] Build succeeded.
Codegen Python for Main
Codegen Python for Control.Bind
Codegen Python for Control.Applicative
Codegen Python for Control.Apply
Codegen Python for Control.Category
Codegen Python for Control.Semigroupoid
Codegen Python for Data.Function
Codegen Python for Data.Boolean
Codegen Python for Data.Ord
Codegen Python for Data.Eq
Codegen Python for Data.HeytingAlgebra
Codegen Python for Data.Symbol
Codegen Python for Type.Proxy
Codegen Python for Data.Unit
Codegen Python for Data.Show
Codegen Python for Record.Unsafe
Codegen Python for Data.Void
Codegen Python for Data.Ordering
Codegen Python for Data.Semigroup
Codegen Python for Data.Ring
Codegen Python for Data.Semiring
Codegen Python for Data.Functor
Codegen Python for Data.Maybe
Codegen Python for Control.Alt
Codegen Python for Control.Alternative
Codegen Python for Control.Plus
Codegen Python for Control.Extend
Codegen Python for Control.Monad
Codegen Python for Control.MonadZero
Codegen Python for Data.Bounded
Codegen Python for Data.Functor.Invariant
Codegen Python for Data.Monoid.Additive
Codegen Python for Data.Monoid
Codegen Python for Data.EuclideanRing
Codegen Python for Data.BooleanAlgebra
Codegen Python for Data.CommutativeRing
Codegen Python for Prelude
Codegen Python for Data.DivisionRing
Codegen Python for Data.Field
Codegen Python for Data.NaturalTransformation
Codegen Python for Data.Monoid.Alternate
Codegen Python for Control.Comonad
Codegen Python for Data.Newtype
Codegen Python for Data.Monoid.Conj
Codegen Python for Data.Monoid.Disj
Codegen Python for Data.Monoid.Dual
Codegen Python for Data.Monoid.Endo
Codegen Python for Data.Monoid.Multiplicative
Codegen Python for Data.Semigroup.First
Codegen Python for Data.Semigroup.Last
Codegen Python for Safe.Coerce
Codegen Python for Unsafe.Coerce
Codegen Python for Data.Generic.Rep
Codegen Python for Effect
Codegen Python for Effect.Console
๐Ÿ
[1]    3845030 segmentation fault (core dumped)  pspy --run

Expected output

Same as purescript (Just 2)

Appendix

Probably just the example repo being outdated

[1] When trying to run spago build at this stage, I get this error:

[error] Oh noes! It looks like the PureScript version installed on your system is not compatible with the package-set you're using.

installed `purs` version:    0.14.5
minimum package-set version: 0.13.6

There are a few ways to solve this:
- install a compatible `purs` version (i.e. in the same 'semver range' as the one in the package set)
- if the `purs` version is 'too new', you can try using `spago upgrade-set` to upgrade to the latest package set
- if you know what you're doing and you want to disable this check, you can override the `version` of the `metadata` package in the packages.dhall, e.g.:

  let upstream = <package-set url here>
  in  upstream
    with metadata.version = "v0.14.5"

[2] When trying to run spago build at this stage, I get this error

[error] Some of your project files import modules from packages that are not in the direct dependencies of your project.
To fix this error add the following packages to the list of dependencies in your config:
- prelude
You may add these dependencies by running the following command:
spago install prelude

A tracker for the membership of purescript-python organization

Firstly let us welcome @mikesol to be a member of purescript-python.

I think we will have more members in the future.

We seems to be working on the first attempt to connect Python to serious and professional functional programming: we have a modern static compiler by purescript, and we can fully use Python's ecosystem and a major part of purescript's ecosystem. This is awesome and, one of what I dreamed a lot years ago.

Like how PEP guys use GitHub issues as a tracker, I want to do this as well.
Let us leave this issue as a tracker for the membership of purescript-python, or if you have better suggestions for related items, please post it here.

Better debugging when lambdas are called

I've been getting a few errors coming from lambdas being invoked correctly, and I'm having trouble debugging them. Here's one as an example:

File ".spago/simple-json/v7.0.0/src/Simple/JSON.purs", line 1, in None
    module Simple.JSON
  File ".spago/prelude/v4.1.1/src/Control/Bind.purs", line 1, in None
    module Control.Bind
  File ".spago/simple-json/v7.0.0/src/Simple/JSON.purs", line 1, in None
    module Simple.JSON
TypeError: lambda:32() takes 0 positional arguments but 1 was given

The actual file JSON.py does not have any calls to lambda, so my guess is that the lambda invocation happens in another file. The issue is that the name of the lambda is not descriptive enough to know where the error occurred. Running pspy using pdb does not help locate the error, either.

Any ideas for how to debug this? Thanks!

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.