Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[WIP] Sudoku solver #10

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
forki wants to merge 1 commit into kjnilsson:master
base: master
Choose a base branch
Loading
from forki:sudoku
Open

[WIP] Sudoku solver #10

forki wants to merge 1 commit into kjnilsson:master from forki:sudoku

Conversation

@forki
Copy link
Contributor

@forki forki commented Jun 17, 2017

after applying #9 I tried to compile my sudoku solver. but no luck:

image

Copy link
Owner

Yes lots of unsupported/not implemented apis here. In general FSharp.Core is patchily implemented and I wasn't planning on even attempting to support System.* as it is very OO / imperative. I'd suggest you rewrite it in a more functional style using only the standard fsharp library. There is no benefit with using stuff like ResizeArray as the only way to support it would be to translate it into a functional equivalent using lists. Also replace Arrays with Lists as there is no erlang equivalent. (well I am thinking we could eventually map byte array to bitstring()).

n * count + m

let boxes (sudoku:Sudoku) =
let d = sudoku |> Array.length |> float |> System.Math.Sqrt |> int
Copy link
Owner

@kjnilsson kjnilsson Jun 17, 2017
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of System.Math.Sqrt we can implement sqrt in Microsoft.FSharp.Core.Operators.erl (or whereever that lives in FSharp.Core).

let start = System.DateTime.Now
let solution = getFirstSolution sudoku

printfn "%As" <| System.Math.Round((System.DateTime.Now - start).TotalSeconds,2)
Copy link
Owner

@kjnilsson kjnilsson Jun 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of System.DateTime use interop to call the erlang equivalent (erlang:system_time/1).

Copy link
Owner

@kjnilsson kjnilsson Jun 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively you could try creating an erlang module named System.erl with a DateTime.Now/0 function in it. That might work as well as fez will translate calls in that way. (check .core output for what it actually worked out).

Copy link
Contributor Author

forki commented Jun 17, 2017

One of the really really great things about fable is that it replaces all such things and the Sudoku solver just works in Javascript.

My personal dream would be that I can take my domain model code und just compile it to beam. Without mapping all the apis manually. I know that's a very long way. But that would be a nice goal.

Copy link
Contributor

0ff1ane commented Jun 17, 2017 via email

Unfortunately, f# is a second class citizen on its native platform, common actions like type-casting throw exceptions instead of using option/either types. And the OOP is pervasive. I was looking into implementing Char, Regex and Match but it would need to support some of the methods that they inherit from the c# Object hierarchy downwards.
...
-- Siddarth
On 18-Jun-2017 2:14 AM, "Steffen Forkmann" ***@***.***> wrote: One of the really really great things about fable is that it replaces all such things and the Sudoku solver just works in Javascript. My personal dream would be that I can take my domain model code und just compile it to beam. Without mapping all the apis manually. I know that's a very long way. But that would be a nice goal. — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub <#10 (comment)>, or mute the thread <https://github.com/notifications/unsubscribe-auth/AHxDp-8wJkLUyeY1SgvCJCJG04J2pWO6ks5sFDq2gaJpZM4N9S2D> .

Copy link
Owner

Well we'll see how far we can take it but System.* is a .NET thing and fez isn't. I don't know how fable are covering System but I can't imagine it being anywhere near complete. It should be easy enough to cover the bits you need on a case by case basis or rewrite code in a functional style. For example mutation doesn't exist in core erlang so code that uses it just won't translate which is the main reason this code does not compile. Any attempt to emulate it are likely to be worse than writing it functionally which makes me reluctant to do it at this point. Same with subtype polymorphism. Although there is some limited support for interfaces and methods already on records and DUs.

I could imagine System being supported through a separate library with System modules being implemented in erlang. Still mutation will be an issue here as well but simple static methods would work ok.

Copy link
Contributor Author

forki commented Jun 18, 2017

@alfonsogarciacaro could you please comment a bit a out how fable deals with this? Or give some pointers? Thx

@forki forki closed this Jun 18, 2017
@forki forki reopened this Jun 18, 2017
Copy link
Contributor

0ff1ane commented Jun 18, 2017 via email

The Fable compatibility docs are what I've been looking at, you might find some answers there. https://fable-compiler.github.io/docs/compatibility.html If we can gain parity with those, we'd be in a good place I think.
...
On Sun, Jun 18, 2017 at 2:13 PM, Steffen Forkmann ***@***.***> wrote: Reopened #10 <#10>. — You are receiving this because you commented. Reply to this email directly, view it on GitHub <#10 (comment)>, or mute the thread <https://github.com/notifications/unsubscribe-auth/AHxDpxyn6M3LL6QeM4YKAD8AVzQvhahKks5sFOMagaJpZM4N9S2D> .

Copy link
Contributor Author

forki commented Jun 18, 2017

Yes fable doesn't support every api in the BCL. But enough to be super useful and to basically allow me to transpile our complete domain model without rewrites.

Copy link
Owner

kjnilsson commented Jun 18, 2017 via email

The problem will always be mutation. Supporting the non mutable subset would be possible but ideally as a separate optional set of erlang modules.
...
On 2017年6月18日 at 10:36, Steffen Forkmann ***@***.***> wrote: @alfonsogarciacaro <https://github.com/alfonsogarciacaro> could you please comment a bit a out how fable deals with this? Or give some pointers? Thx — You are receiving this because you commented. Reply to this email directly, view it on GitHub <#10 (comment)>, or mute the thread <https://github.com/notifications/unsubscribe-auth/ABIDlP52Y1lrOkhucUezVtaMmfq-T78Uks5sFOMYgaJpZM4N9S2D> .

Copy link
Contributor

0ff1ane commented Jun 18, 2017

Yes, we probably need to change how we approach the problems a bit.

Makes it more interesting 😄
One erlang way to write a sudoku solver would probably be to have each cell as a process with their co-ordinates and a set of possible values, and whittle the set down by talking to the others in the same row/column till they converge(or not)?

Copy link
Contributor Author

forki commented Jun 18, 2017

Just to make this super clear. My problem is not to write a Sudoku solver. This is just some random snippet.

My interest is to use existing domain code and run it in things like Phoenix. This would allow me to use the same domain logic in my Javascript clients, my suave app and if needed I can port it to a different platform when I have good reasons for that

Lleutch and wallymathieu reacted with thumbs up emoji

Copy link
Owner

kjnilsson commented Jun 18, 2017 via email

And that will be possible the more functional your approach is. Sure we can probably rewrite imperative code using recursion. We may even be able to support local mutable fields using the process dictionary but the benefits would be scant and it may lead users to the wrong conclusions (e.g. Mutation is faster). Wouldn't it be better to focus on supporting the paradigm that works best? I'm not saying it's off the table only lower down on priorities.
...
On 2017年6月18日 at 11:36, Steffen Forkmann ***@***.***> wrote: Just to make this super clear. My problem is not to write a Sudoku solver. This is just some random snippet. My interest is to use existing domain code and run it in things like Phoenix. This would allow me to use the same domain logic in my Javascript clients, my suave app and if needed I can port it to a different platform when I have good reasons for that — You are receiving this because you commented. Reply to this email directly, view it on GitHub <#10 (comment)>, or mute the thread <https://github.com/notifications/unsubscribe-auth/ABIDlOZtmQnslEH0jzKuRCmSbOsXQepmks5sFP2wgaJpZM4N9S2D> .

Copy link
Contributor Author

forki commented Jun 18, 2017 via email

Absolutely. Tbh my domain models don't really have mutable state. I'm just saying if we support basic things like dictionaries, list, array and so on then it would be great Am 18.06.2017 12:51 nachm. schrieb "Karl Nilsson" <notifications@github.com
...
: And that will be possible the more functional your approach is. Sure we can probably rewrite imperative code using recursion. We may even be able to support local mutable fields using the process dictionary but the benefits would be scant and it may lead users to the wrong conclusions (e.g. Mutation is faster). Wouldn't it be better to focus on supporting the paradigm that works best? I'm not saying it's off the table only lower down on priorities. On 2017年6月18日 at 11:36, Steffen Forkmann ***@***.***> wrote: > Just to make this super clear. My problem is not to write a Sudoku solver. > This is just some random snippet. > > My interest is to use existing domain code and run it in things like > Phoenix. This would allow me to use the same domain logic in my Javascript > clients, my suave app and if needed I can port it to a different platform > when I have good reasons for that > > — > You are receiving this because you commented. > > > Reply to this email directly, view it on GitHub > <#10 (comment)>, or mute > the thread > <https://github.com/notifications/unsubscribe-auth/ ABIDlOZtmQnslEH0jzKuRCmSbOsXQepmks5sFP2wgaJpZM4N9S2D> > . > — You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub <#10 (comment)>, or mute the thread <https://github.com/notifications/unsubscribe-auth/AADgNH6X3f2YK4A_Z9VK548Wt-SweVDJks5sFQEvgaJpZM4N9S2D> .

Copy link
Contributor Author

forki commented Jun 19, 2017

sorry if the following is completely stupid.

Can we use ETS tables to emulate Lists and dictionaries? https://elixir-lang.org/getting-started/mix-otp/ets.html

Maybe something along the lines of:

type List<'a>() =
 let name = createRandomName()
 let self = emit (sprintf ":ets.new(:%s, [:named_table])" name)
 emit (sprintf ":ets.insert(:%s, {\"list\", [])" name)
 with
 member this.Item(pos:int) : 'a =
 let current = emit (sprintf ":ets.lookup(:%s, \"list\")" name)
 current.[pos] :> 'a
 member this.Add<'a>(x:'a) =
 let current = emit (sprintf ":ets.lookup(:%s, \"list\")" name)
 let all = x::current
 emit (sprintf ":ets.insert(:%s, {\"list\", all)" name)

Maybe this is not the nicest thing on earth, but could it work? as a first hacky version?

Copy link
Contributor

0ff1ane commented Jun 19, 2017

I think its doable with some caveats.

ets is a bit tricky, the table-names are global to all processes.
So we would need to use name-mangling and manage that internally.

And the table exists till the parent process gets killed, or the table is sent a delete message.
Maybe that could be done using finalize()?

There also seems to be a upper limit on number of tables per erlang node(around 1400 by default).

This seems like a good idea to get around some of the places where it is impossible to do things immutably.
But I'm afraid people might overuse this. 😨

Although having a nice f#ish wrapper around ets for in-memory storage would be fantastic!!
With type providers hooking into ets tables etc.

Copy link
Contributor Author

forki commented Jun 19, 2017

it was an idea to get things started. maybe someone can implement it and later we improve on it

Copy link
Owner

ok I was playing with this earlier and accidentally committed soduku.fs to the master branch. I had to make two minor changes and now it compiles but it won't run as it is calling a load of unimplemented apis. If anyone feels like it you can compile it and look at the soduku.core file to see what erlang/elixir modules and functions would need to be implemented to make it work.

er ETS - they don't have to be named but it may be better to use the process dictionary to implement List<T>.

Copy link
Owner

I hacked up a potential process dictionary backed List<_> implementation. Again it suffers the same shortcoming as ref cells and lazy in that there is no gc.

dd63391

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@kjnilsson kjnilsson kjnilsson left review comments

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

AltStyle によって変換されたページ (->オリジナル) /