Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Nov 09 12:09
    jnoortheen commented #537
  • Nov 05 06:05
    fabianhjr commented #540
  • Nov 05 06:05
    fabianhjr commented #540
  • Nov 05 04:03
    evhub commented #560
  • Nov 05 04:02
    evhub closed #560
  • Nov 05 04:02
    evhub commented #560
  • Nov 05 04:02
    evhub milestoned #560
  • Nov 05 04:02
    evhub labeled #560
  • Nov 05 04:02
    evhub edited #560
  • Nov 03 21:51
    fabianhjr opened #560
  • Nov 01 07:35
    eindiran commented #50
  • Nov 01 07:34
    eindiran commented #50
  • Nov 01 00:50
    JeffreyBenjaminBrown commented #50
  • Oct 31 05:52
    timka commented #50
  • Oct 31 02:08
    evhub closed #559
  • Oct 31 02:08
    evhub commented #559
  • Oct 31 02:08
    evhub labeled #559
  • Oct 31 02:08
    evhub labeled #559
  • Oct 31 02:08
    evhub milestoned #559
  • Oct 31 00:34
    bj0 opened #559
ShalokShalom
@ShalokShalom
@evhub Please, I do like to see the integration of the pipe operator in Coconut? Do you do that with map? Can I see it?
Evan Hubinger
@evhub
@ShalokShalom I don't understand your question. Are you asking for Coconut's internal implementation of the pipe operator? The bulk of that can be found here, if that's what you're looking for.
Honestly, though, if you just want to understand how pipe works, it'd probably be easier to just use coconut --display to look at what various different uses of the pipe operator compile to.
ShalokShalom
@ShalokShalom
No, this is exactly what I was looking for
Why is this so imperative? Wouldnt it be far more easy, to use map?
I consider to implement a pipe in another language, that is very similar to Python, and try to look for inspiration. Is that for performance reasons so imperative?
Evan Hubinger
@evhub
@ShalokShalom How else would you compile x |> f other than to f(x)? There's nothing map-like going on with pipe, it's just function calls. And function calls are obviously very functional.
Genesis
@TheExGenesis

Hey Evan, thanks for your amazing work!

I was wondering what the right way to configure vscode to use coconut inside the interactive python REPL thing/ embedded notebooks. Already installed coconut --jupyter

Evan Hubinger
@evhub
@TheExGenesis Thanks! I don't use VSCode very much myself so I have no idea, but you're welcome to raise an issue for it. Certainly if VSCode has Jupyter support you can try to configure it to use the coconut kernel, but I don't know enough about VSCode to know how to do that.
Russ Abbott
@RussAbbott
Hi, I'm trying to install Coconut on Google colab. It seems to install, but it doesn't run. Please see my StackOverflow question. https://stackoverflow.com/questions/63965737/is-it-possible-to-run-coconut-on-colab. Thanks.
Russ Abbott
@RussAbbott
When I tried the iterator version of quick_sort in the online interpreter, I got a syntax error on the yield from line.
Evan Hubinger
@evhub
@RussAbbott It looks to me like you successfully installed Coconut, but didn't actually switch to the Coconut kernel rather than the Python kernel.
Russ Abbott
@RussAbbott
So, how do you tell colab to switch to the Coconut kernel?
vinodh
@rawvnode

hello, i'm a super noob to functional programming and the Coconut language. I went over the tutorial section to get a grasp of few of the concepts and was hoping to apply some of the learnings to a messy piece of code but i'm struggling to get started.

my current solution is to create layers of nesting to get some values out of a json object. i'm looking for some advise on how to take a functional approach to solve this problem.

here is my test json

{
    "mobile/stats": {
        "nestedStats": {
            "kind": "stats",
            "entries": {
                "activeMemberCnt": {
                    "value": "3"
                },
                "totRequests": {
                    "value": 600
                },
                "mobile/members/stats": {
                    "nestedStats": {
                        "entries": {
                            "firePunch/stats": {
                                "nestedStats": {
                                    "entries": {
                                        "power": {
                                            "value": 25
                                        },
                                        "pp": {
                                            "value": 10
                                        },
                                        "type" : {
                                            "value" : "Fire"
                                        }
                                    }
                                }
                            },
                            "icePunch/stats": {
                                "nestedStats": {
                                    "entries": {
                                        "power": {
                                            "value": 75
                                        },
                                        "pp": {
                                            "value": 15
                                        },
                                        "type" : {
                                            "value" : "Ice"
                                        }
                                    }
                                }
                            },
                            "karateChop/stats": {
                                "nestedStats": {
                                    "entries": {
                                        "power": {
                                            "value": 25
                                        },
                                        "pp": {
                                            "value": 10
                                        },
                                        "type" : {
                                            "value" : "Fighting"
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
and my messy piece of current code
stats = {}
for k, v in test_json.items():
    for kk, vv in v.items():
        if 'nestedStats' in kk:
            for kkk, vvv in vv.items():
                if 'entries' in kkk:
                    for kkk1, vvv1 in vvv.items():
                        if '/stats' in kkk1:
                            for kkkk, vvvv in vvv1.items():
                                for kkkkk, vvvvv in vvvv.items():
                                    for kkkkkk, vvvvvv in vvvvv.items():
                                        for kkkkkkk, vvvvvvv in vvvvvv.items():
                                            for kkkkkkkk, vvvvvvvv in vvvvvvv.items():
                                                stats[kkkkkk] = vvvvvvvv


poke_stats = json.dumps(stats).replace('\'', '"').replace('description', '').replace('{"":', '').replace('{"value":', '').replace('},', ',')[:-1]
Evan Hubinger
@evhub
@rawvnode You could use map and filter instead of for loops, but I don't actually know whether that'll help that much here.
ShalokShalom
@ShalokShalom
@evhub Oh, somebody told me, that pipes are implemented with map or reduce, so I thought..
matrixbot
@matrixbot

nalix > <@gitter_rawvnode:matrix.org> hello, i'm a super noob to functional programming and the Coconut language. I went over the tutorial section to get a grasp of few of the concepts and was hoping to apply some of the learnings to a messy piece of code but i'm struggling to get started.

my current solution is to create layers of nesting to get some values out of a json object. i'm looking for some advise on how to take a functional approach to solve this problem.
test json
```

The function approach to deeply nested data structures is lenses (at least the only one I know of). This seems like what you'd need, though I haven't used the package myself.

nalix * The functional approach to deeply nested data structures is lenses (at least the only one I know of). This seems like what you'd need, though I haven't used the package myself.
vinodh
@rawvnode
@evhub @matrixbot nalix thanks for the pointers
vinodh
@rawvnode

i think i've somewhat simplified the code to be slightly less convoluted by adding a few things...

also i made a few assumptions to reduce the complexity within the flow like separating the logic to handle parent stats and its member stats.

the new function walks along the json tree path going from parent, child all the way down until it encounters an attribute labeled "value" and add its value to the member_stats dict when there is a match and the value is of type int. The key will be the second but previous element in the path list.

I've replaced the deep nesting of for loops with a recursive function. I'm hoping to add more features like pattern matching and map/filter if possible and also eliminate the global level dicts to manage state :)

parent_stats = {}
member_stats = {}

def traverse(obj, path=None):
    if path is None:
        path = []

    if isinstance(obj, dict):
        value = { k: traverse(v, path + [k]) for k, v in obj.items()}
    elif isinstance(obj, int):
        value = obj
        if "value" in path:
            node_key = list(filter(lambda x: re.search('https.*members.*members/(.+)/stats\Z', x), path))
            if node_key:
                if node_key[0] not in member_stats.keys():
                    member_stats[node_key[0]] = {path[-2] : value}
                else:
                    member_stats[node_key[0]].update({path[-2] : value})
            else:
                parent_stats[path[-2]] = value
    else:
        value = obj
    return value

traverse(poke_stats)
vinodh
@rawvnode
@matrixbot nalix i will look into the lens project but i am hoping to achieve some benefits of using coconut now that this version is somewhat readable than the earlier version :) any thoughts?
vinodh
@rawvnode
sorry one more text to show the desired flattened output -
parent_stats

{
    "mobile/stats": {
        "activeMemberCnt" : 3,
        "totRequests" : 600
    }
}

member_stats

{
    "firePunch/stats" : {
        "power" : 25,
        "pp" : 10
    },
    "icePunch/stats" : {
        "power" : 25,
        "pp" : 15
    },
    "karateChop/stats" : {
        "power" : 25,
        "pp" : 10
    }
}
ShalokShalom
@ShalokShalom
@evhub Pattern matching comes in Python 3.10
Coconut does a) ignore this or b) ditches its own pattern matching?
Or some c)
ShalokShalom
@ShalokShalom
And is there a way that I can alligne the pipe operators in the new line, like this:
ShalokShalom
@ShalokShalom
This is how FSharp does it and it allows you to do lots of neat things, by creating a chain of pipes, all neatly sorted beyond each other.
ShalokShalom
@ShalokShalom
And I struggle to find the Pygments lexer for Coconut here, you said in the documentation it exists:
ShalokShalom
@ShalokShalom
I found a way to use pipes vertically, you could include that in your documentation, since this is how every single F# and Elm developer uses pipes
Thurston Sexton
@tbsexton

@ShalokShalom the typical way to use vertical pipes is with parenthetical continuation:

("hello world"
 |>.upper
 |> print
)

etc.

Thurston Sexton
@tbsexton

@evhub Im planning to use data to build a toolkit around network analysis. The big issue with graph data structures I've encountered is the need to constantly keep track of whether you're using an edge-oriented function or a node-oriented one. So, does my function operate on adjacency matrices, edgelists, etc.

The most elegant way I've seen this done imo is tidygraph https://tidygraph.data-imaginist.com/ which lets you switch modes.

in my case, I would like to build a graph data object that stores both. Then, there are functions that work on either adjacency matrices, or on edgelists, etc. I would like to be able to pass a graph object to those functions and have them behave like the correct contents were passed

my intuition is to write a pattern-matching fmap to turn the graph object into a sort of two-faced functor: if the function passed to fmap accepts e.g. square matrices, the fmap uses the adjacency representation....if it accepts lists/vectors, it instead uses the edgelist view.

A bit of a functional noob here, so just wanting some feedback if this is something ridiculous to do, w.r.t. coconut's design haha

I should clarify, a pattern-matching __fmap__
Thurston Sexton
@tbsexton

the other way is to have to manually specify for every function whether it uses the edge or node view. the problem is, I would like to write them in terms of straight np.array or jax.numpy.array objects, and having to add a

@addpattern(myfunc)
def myfunc(g is graph)=
    myfunc(g.adjacency)

seems like a lot of extra boilerplate...

Cristhian Motoche
@CristhianMotoche

Hello! I'm just starting with coconut and I'm integrating it with mypy. I created a simple hello world example

"hello world" |> print

and I tried to compile it integrating it with mypy:

coconut run.coco --mypy

but I'm getting this odd error:

Compiling         run.coco ...
Compiled to       run.py .
$HOME/.coconut_stubs/__coconut__.pyi:81: error: Module has no attribute "abc"
Found 1 error in 1 file (checked 1 source file)
Exiting due to MyPy error.

What could be the cause of this error?

FYI, I'm using a virtual environment and Python 3.7.

Evan Hubinger
@evhub
@CristhianMotoche It looks like mypy is getting mad at Coconut using collections.abc, which is strange because it be available on Python 3.7. First, just try uninstalling coconut and reinstalling the latest dev version by running pip install --upgrade coconut-develop[mypy] and see if that fixes the issue. If not, try running coconut run.coco --target sys --mypy instead, which should tell mypy to check according to the current Python version.
Cristhian Motoche
@CristhianMotoche
Thanks for the response @evhub . I tried both options but they didn't work. Maybe the verbose output of the compiler can help to identify the issue:
(coconut-sample-fvM68vJh-py3.7) ➜  coconut-sample git:(master) ✗ coconut run.coco  --verbose --mypy
Using Cython cPyparsing v2.4.5.
Parsed args: Namespace(argv=None, code=None, dest=None, display=False, documentation=False, force=False, history_file=None, interact=False, jobs=None, jupyter=None, keep_lines=False, line_numbers=False, minify=False, mypy=[], no_tco=False, no_write=False, package=False, quiet=False, recursion_limit=None, run=False, source='run.coco', standalone=False, strict=False, style=None, target=None, tutorial=False, verbose=True, watch=False)
Compiler args: {'target': '', 'strict': False, 'minify': False, 'line_numbers': False, 'keep_lines': False, 'no_tco': False}
MyPy args: ['--python-version', '3.7', '--warn-incomplete-stub', '--warn-redundant-casts', '--warn-return-any', '--warn-unused-configs', '--show-error-context']
Hash args: {'VERSION_STR': '1.4.3 [Ernest Scribbler]', 'reduce_args': ('', False, False, False, False, False), 'package_level': 0}
Compiling         $HOME/Documents/code/Coconut/coconut-sample/run.coco ...
Hash args: {'VERSION_STR': '1.4.3 [Ernest Scribbler]', 'reduce_args': ('', False, False, False, False, False), 'package_level': 0}
Time while parsing: 1.245418 seconds
Packrat parsing stats: 494 hits; 6419 misses
Compiled to       $HOME/Documents/code/Coconut/coconut-sample/run.py .
Traceback (most recent call last):
  File "$HOME/.cache/pypoetry/virtualenvs/coconut-sample-fvM68vJh-py3.7/lib/python3.7/site-packages/coconut/command/util.py", line 300, in symlink
    os.symlink(link_to, link_from, target_is_directory=True)
FileExistsError: [Errno 17] File exists: '$HOME/.cache/pypoetry/virtualenvs/coconut-sample-fvM68vJh-py3.7/lib/python3.7/site-packages/coconut/stubs' -> '$HOME/.coconut_stubs'
MYPYPATH = $HOME/.coconut_stubs
> mypy $HOME/Documents/code/Coconut/coconut-sample/run.py --python-version 3.7 --warn-incomplete-stub --warn-redundant-casts --warn-return-any --warn-unused-configs --show-error-context
run.py:16: note: In module imported here:
$HOME/.coconut_stubs/__coconut__.pyi: note: In class "_coconut":
$HOME/.coconut_stubs/__coconut__.pyi:81: error: Module has no attribute "abc"
Found 1 error in 1 file (checked 1 source file)
Exiting due to MyPy error.
Eric Anderson
@Nexus6

What a coincidence, I ran face-first into this same issue just last night. I too am in a venv on Linux, but using the Python 3.8.5 from the Manjaro repos. Below are some details of the environment, edited for clarity:
$ coconut -v
Coconut: Version 1.4.3 [Ernest Scribbler] running on Python 3.8.5
$ python
Python 3.8.5 (default, Sep 5 2020, 10:50:12)
[GCC 10.2.0] on linux

import collections.abc
abc = collections.abc
import sys
sys.version_info
sys.version_info(major=3, minor=8, micro=5, releaselevel='final', serial=0)
sys.version_info > (3,3)
True
sys.version_info < (3,3)
False
$ mypy -V
mypy 0.790
$ coconut -t 38 -j 4 -k --no-tco --force . --mypy
Compiling main.coco ...
Compiled to main.py .

$HOME/.coconut_stubs/coconut.pyi:99: error: Module has no attribute "abc"

It would appear that the mypy error is happening on the "abc = collections.abc" assignment in coconut.pyi which is strange since that works fine in the repl.

Ugh, apologies for the formatting fail. Forgot to mention, using "coconut -t sys ..." did not change the behavior that we're seeing for me.
Evan Hubinger
@evhub
@CristhianMotoche @Nexus6 I think this is an error symlinking the stub file dir—could one of you raise an issue for this?
Eric Anderson
@Nexus6
I checked and on my system ~/.coconut_stubs was a symlink to another Coconut environment, but the wrong one. I don't know how that happened. Nevertheless, after attempting to correct it by reconstituting it to a symlink to my current project, I now have lrwxrwxrwx 1 me me 59 Nov 3 15:46 $HOME/.coconut_stubs -> $HOME/.local/lib/python3.8/site-packages/coconut/stubs and yet I'm still getting, on compile, $HOME/.coconut_stubs/__coconut__.pyi:81: error: Module has no attribute "abc" with no other changes.
Fabien Bourgeois
@Yakulu
@evhub Are pipeline optimizations still here ? The last example compiles to (print)((sq)((_coconut.operator.add)(*(1, 2)))) for me
Instead of print(sq(operator.add(1, 2)))
That said, perhaps there is no performance hit doing like that.
Evan Hubinger
@evhub
@Yakulu Pipeline optimization is what's removing the partial application object. There shouldn't be any meaningful performance hit from any of the other stuff.