PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0
Showing posts with label nim-lang. Show all posts
Showing posts with label nim-lang. Show all posts

Thursday, November 10, 2022

[FIXED] How to call function in Nim based on a number without ifs?

 November 10, 2022     call, nim-lang, proc, procedure     No comments   

Issue

So I want to write a procedure to which I'll pass a number and it will call some other function based on the number I gave it. It could work something like this:

#example procs

proc a(): proc =
  echo 'a'
proc b(): proc =
  echo 'b'

proc callProcedure(x:int): proc =
  if x>5:
    a()
  else:
    b()

callProcedure(10)  #calls function a
callProcedure(1)   #calls function b

However I want to do this without ifs. For example I was looking into somehow storing a reference to the functions in an array and call it via its index but I could not get that to work and I've got the suspicion it cannot be done (in which case I would like to understand why). I am also interested in other ways of achieving the same result. I've got multiple reasons why I want to do this: a) I've read ifs are slow(er-ish) among other things (like that novices should leave optimizing them up to the compiler so I know I don't have to even think about it but I would like to try something like this to learn nonetheless) b) I think it opens up some possibilities like being very dynamic in the order of and which procedures will be called c) just out of curiosity

Some of the things I've looked at in relation to this but could not manage to find/learn what I need from them:

Nim return custom tuple containing proc

Nim stored procedure reference in tuple

PS: I'm very new to this so if I missed something obvious feel free to point me in the right direction.

Thanks in advance!


Solution

You can store procedures in an array just fine, but they have to be of the same type:

proc a() =
  echo "a"

proc b() =
  echo "b"

let procs = [a, b]

proc callProcedure(x: int) =
  procs[int(x <= 5)]()

callProcedure(10)  # Calls function a
callProcedure(1)   # Calls function b

You don't need the "proc" return type. Also this still uses comparisons under the hood for x <= 5, so there's that. And ifs aren't slow.



Answered By - Optimon
Answer Checked By - Robin (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Sunday, July 10, 2022

[FIXED] How do I iterate over the fields of a ref object in nim?

 July 10, 2022     iterator, nim-lang, reference     No comments   

Issue

I have a ref object type and would like to iterate over all of its fields and echo them out.

Here an example of what I want:

type Creature* = ref object
    s1*: string
    s2*: Option[string]
    n1*: int
    n2*: Option[int]
    n3*: int64
    n4*: Option[int64]
    f1*: float
    f2*: Option[float]
    b1*: bool
    b2*: Option[bool]


var x = Creature(s1: "s1", s2: some("s2"), n1: 1, n2: some(1), n3: 2, n4: some(2.int64), f1: 3.0, f2: some(3.0), b1: true, b2: some(true))

for fieldName, fieldValue in x.fieldPairs:
  echo fieldName

However, doing so causes this compiler error:

Error: type mismatch: got <Creature>
but expected one of:
iterator fieldPairs[S: tuple | object; T: tuple | object](x: S; y: T): tuple[
    key: string, a, b: RootObj]
  first type mismatch at position: 1
  required type for x: S: tuple or object
  but expression 'x' is of type: Creature
iterator fieldPairs[T: tuple | object](x: T): tuple[key: string, val: RootObj]
  first type mismatch at position: 1
  required type for x: T: tuple or object
  but expression 'x' is of type: Creature

expression: fieldPairs(x)

Going through the documentation, there appear to be no iterators for ref object types, only for object types. If that's the case, then how do you iterate over ref object types?


Solution

If you want to use iterators, you need to de-reference the ref-type that you want to iterate over! This may also apply to any other proc that expects an object parameter, but that you want to use with a ref object instance.

In nim, the de-referencing operator is [].

So in order to work, the instance x of the ref object type Creature needs to be de-referenced before iterating over it:

for fieldName, fieldValue in x[].fieldPairs:
  echo fieldName

This will also work with any proc you write, for example like this:

proc echoIter(val: object) =
  for fieldName, fieldValue in val.fieldPairs:
    echo fieldName

echoIter(x[])


Answered By - Philipp Doerner
Answer Checked By - Willingham (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Saturday, May 7, 2022

[FIXED] How can one do a pixel by pixel comparison of an image created by cairo and an image loaded from a file

 May 07, 2022     cairo, diff, image, nim-lang     No comments   

Issue

I have some code in nim that creates a picture using Cairo (https://github.com/nim-lang/cairo). I would like to compare that picture to another using diffimg (https://github.com/SolitudeSF/diffimg, https://github.com/SolitudeSF/imageman).

But there does not seem to be a standard in memory image type. Is there any way to do this that does not involve saving the image to a file first?


Solution

Probably the most easy way is surprisingly to implement yourself the diffimg algorithm. Looking at the source of diffimg shows the comparison algoritm is about 20 lines of code:

func absDiff[T: ColorComponent](a, b: T): T {.inline.} =
  if a > b:
    a - b
  else:
    b - a

func getDiffRatio*[T: Color](a, b: Image[T]): float =
  for p in 0..a.data.high:
    for c in 0..T.high:
      result += absDiff(a[p][c], b[p][c]).float
  result / (T.maxComponentValue.float * a.data.len.float * T.len.float)

func genDiffImage*[T: Color](a, b: Image[T]): Image[T] =
  result = initImage[T](a.w, a.h)
  for p in 0..result.data.high:
    for c in 0..T.high:
      result[p][c] = absDiff(a[p][c], b[p][c])

The actual trouble of loading the image is left to imageman, but all in all it seems to substract pixel component values between the two images and create some kind of average/ratio. Since the cairo library seems to generate its own, possibly incompatible, memory layout for images, most likely you want to ignore imageman and load the image you want to compare to yourself into a cairo memory buffer, then replicate the diffing algorithm iterating through the pixels of each caro image. Or maybe convert the cairo buffer to an imageman buffer and let the diffimg implementation do its magic.



Answered By - Grzegorz Adam Hankiewicz
Answer Checked By - Marilyn (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Older Posts Home

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
All Comments
Atom
All Comments

Copyright © PHPFixing