[HN Gopher] Inline Assembly in F#
       ___________________________________________________________________
        
       Inline Assembly in F#
        
       Author : cglong
       Score  : 127 points
       Date   : 2022-02-06 05:55 UTC (1 days ago)
        
 (HTM) web link (blog.devgenius.io)
 (TXT) w3m dump (blog.devgenius.io)
        
       | rwmj wrote:
       | It's the one thing I wish OCaml had.
        
       | barrenko wrote:
       | F# is damn cool.
        
         | udbhavs wrote:
         | As someone who wants to learn it and has never used the .NET
         | ecosystem, do I need to become familiar with the standard
         | library and packages through C# first or is it okay if I dive
         | directly into F#?
        
           | gameswithgo wrote:
           | To start learning you don't need any C# experience, to build
           | practical things you will probably need to develop a little,
           | to be able to interact with libraries in the C# ecosystem.
        
           | barrenko wrote:
           | I did have some experience with .NET but I think the overall
           | consensus is - not really. "Functional" experience will be
           | more helpful.
           | 
           | Also funny I never really understood C# / .NET packages
           | _until_ F# because it 's way simpler and less abstracted.
        
           | jaywalk wrote:
           | As a C# developer with no F# experience besides looking at
           | code in articles like this, I don't see any reason why you'd
           | need to start with C# if you're just looking to learn F#.
        
             | ReleaseCandidat wrote:
             | You don't need to start with it, but you do need to
             | understand C# code to actually use most of .Net and 3rd
             | party libraries. Same when you're using another language
             | than Javascript that compiles to Javascript and same with
             | the JVM and Java, I guess.
        
           | owenm wrote:
           | I was in a similar position when I started learning F# - I'd
           | say start with F#, but you will likely need to be able to
           | read through some of the C# examples to work out how to do
           | common things that rely on the .NET standard library if you
           | haven't worked with .NET before (for example, if you want to
           | read the contents of a file into memory, it's simple, but the
           | examples on the MS site are in C# here and would need a small
           | amount of translating: https://docs.microsoft.com/en-
           | us/dotnet/standard/io/how-to-r...).
        
       | choeger wrote:
       | Nice hack. What happens if you run it on an unsupported platform?
       | At the very least, I'd expect a runtime exception, ideally on
       | startup. But how do you check whether you can actually evaluate
       | that assembly with the given ABI?
        
         | ReleaseCandidat wrote:
         | > But how do you check whether you can actually evaluate that
         | assembly with the given ABI?
         | 
         | AFAIK you cannot get the RID at runtime, but you can easily set
         | the RID of your program/package to the supported platforms only
         | 
         | https://docs.microsoft.com/en-us/dotnet/core/rid-catalog
        
         | MisterTea wrote:
         | > But how do you check whether you can actually evaluate that
         | assembly with the given ABI?
         | 
         | I'd avoid assembler unless its separated into an architecture
         | specific file. Otherwise this hack is asking for trouble.
        
       | petercooper wrote:
       | Got the same vibe reading this as I did when introduced to Turbo
       | Pascal 7's inline x86 support back in the day. Very seamless and
       | absolutely fantastic for games/demo programming in particular :-)
        
       | tempodox wrote:
       | Wonderfully crazy. Does it only work on Windows?
        
         | gameswithgo wrote:
         | As written it would only work on Windows but in principle it
         | should be achievable on all platforms
        
         | aaronmu wrote:
         | It runs on Windows, Linux, and macOS.
         | 
         | https://dotnet.microsoft.com/en-us/learn/dotnet/what-is-dotn...
        
           | ygra wrote:
           | Not by calling VirtualAlloc and friends, though. At least
           | that part of the code has to be rewritten per platform.
        
           | tempodox wrote:
           | I know that .NET is cross-platform, that was not my point.
           | I'm referring to the parts where the article specifically
           | mentions Windows API. How do I do the same on macOS and
           | Linux? Is it even possible?
        
             | atdrummond wrote:
             | I don't see anything that doesn't have mac/Linux analogues
             | but it would definitely require a concerted effort.
        
       | Serow225 wrote:
       | F# CE is so cool
        
         | peheje wrote:
         | It is.
         | 
         | One thing I don't get about the async story in Computation
         | Expressions is the sudden need for you to think about
         | return/return!
         | 
         | Couldn't CE continue to use "return by last statement" and then
         | do the CE-invoking version with exclamation mark in the end?
         | 
         | let private readUrls () = async { (IO.File.ReadAllLinesAsync
         | "urls.txt" |> Async.AwaitTask)! }
         | 
         | Would probably break something I haven't thought about.
         | 
         | Also the whole task vs async confusion is a bit difficult to
         | wrap your head around. I understand .net6 introduced task {}
         | CE, but you still need to have two stories in your head and
         | convert back and forth and use async {}
        
       | buybackoff wrote:
       | The problem with methods such as GetCPUCyles or GetCPUCoreId is
       | that .NET delegate calls are never inlined. Unmanaged calli calls
       | are not inlined either. PInvokes could be inlined but have their
       | own overheads for managed<->native transition. These overheads
       | could be higher than a small method body. It would be really cool
       | to generate function pointers with the default managed calling
       | convention, basically what JIT does for normal methods. I mean,
       | packing assembly into the body of a managed function, which has a
       | chance to be inlined.
        
       | david_allison wrote:
       | This is awesome!
       | 
       | > First, F# doesn't support function pointers
       | 
       | As an experiment, can you work around this with the (deprecated)
       | inline CIL operator: (# ... #)
       | 
       | https://stackoverflow.com/questions/15968054/what-is-the-syn...
        
         | piaste wrote:
         | Unfortunately that syntax is a little troublesome to use.
         | 
         | To enable it, you need to add the --compiling-fslib flag, which
         | basically declares "hi i want to build a stdlib, I know what
         | I'm doing (the flag is undocumented btw)" and as a result it
         | doesn't include the FSharp.Core library and all the built-in
         | modules.
         | 
         | So your code fails to compile because it doesn't know 'string'
         | or 'printf', AFAIK manually adding the reference isn't enough,
         | you would need to statically include all the FSharp.Core source
         | code.
        
       ___________________________________________________________________
       (page generated 2022-02-07 23:02 UTC)