M
Modular3mo ago
Anindya

How to declare a function type in a trait?

This is a simple class in Python
class MyPair:
def __init__(first, second):
self.first = first
self.second = second

def _hello():
return None

self._hi = _hello
class MyPair:
def __init__(first, second):
self.first = first
self.second = second

def _hello():
return None

self._hi = _hello
Now I thought I could this in Mojo in someway but stucked
struct MyPair:
var first: Int
var second: Int
var _hi

fn __init__(inout self, first: Int, second: Int):
self.first = first
self.second = second
fn _hello():
return None

self._hi = _hello
struct MyPair:
var first: Int
var second: Int
var _hi

fn __init__(inout self, first: Int, second: Int):
self.first = first
self.second = second
fn _hello():
return None

self._hi = _hello
Is there any possible way of doing this in Mojo? Error:
error: Expression [17] wrapper:22:13: struct field declaration must have a type
var _hi
^
error: Expression [17]:12:13: 'MyPair' value has no attribute '_hi'
self._hi = _hello
error: Expression [17] wrapper:22:13: struct field declaration must have a type
var _hi
^
error: Expression [17]:12:13: 'MyPair' value has no attribute '_hi'
self._hi = _hello
9 Replies
mad alex 1997
mad alex 19973mo ago
You have to set the type to match the function signature. And Fn functions must explicitly return there type.
struct MyPair:
var first: Int
var second: Int
var _hi: fn()->None

fn __init__(inout self, first: Int, second: Int):
self.first = first
self.second = second
fn _hello()->None:
return None

self._hi = _hello
struct MyPair:
var first: Int
var second: Int
var _hi: fn()->None

fn __init__(inout self, first: Int, second: Int):
self.first = first
self.second = second
fn _hello()->None:
return None

self._hi = _hello
But this makes for an inflexible _hello function as now it must return None.
ModularBot
ModularBot3mo ago
Congrats @mad alex 1997, you just advanced to level 11!
Anindya
Anindya3mo ago
Thanks for the answer, so is it not possible to be more flexible with this apperoach in any ways?
mad alex 1997
mad alex 19973mo ago
Not without doing something weird, strong typing is a double edged sword.
Anindya
Anindya3mo ago
I see, but still it is a good start, thanks and now I am starting to see the cons of strong typings .. ughh
mad alex 1997
mad alex 19973mo ago
Technically if you are willing to do something verbose and your functions don't need parameters (I'll put in a bug report for it tomorrow) only arguments.
fn a()->None:
print("a")
return None

fn b(i:Int)->Int:
print(i)
return i*2

def main():
var func: Variant[fn()->None,fn(i:Int)->Int]
func = a
if func.isa[fn()->None]():
func._get_ptr[fn()->None]()[0]()
func = b
if func.isa[fn(i:Int)->Int]():
var res = func._get_ptr[fn(i:Int)->Int]()[0](1)
print(res)
fn a()->None:
print("a")
return None

fn b(i:Int)->Int:
print(i)
return i*2

def main():
var func: Variant[fn()->None,fn(i:Int)->Int]
func = a
if func.isa[fn()->None]():
func._get_ptr[fn()->None]()[0]()
func = b
if func.isa[fn(i:Int)->Int]():
var res = func._get_ptr[fn(i:Int)->Int]()[0](1)
print(res)
Anindya
Anindya3mo ago
Hi, so there was one more problem I am facing
from python import Python


struct Module:
var func_module: PythonObject

fn __init__(inout self, module_path: String):
try:
Python.add_to_path(module_path)
self.func_module = Python.import_module("func")
except Exception:
pass
from python import Python


struct Module:
var func_module: PythonObject

fn __init__(inout self, module_path: String):
try:
Python.add_to_path(module_path)
self.func_module = Python.import_module("func")
except Exception:
pass
So, in any how I was not able to initialize my func_module which is taken from func.py file. I got to insert it under try block other wise giving me error, and once that done, I am getting this kind of error:
/Users/anindyadeepsannigrahi/workspace/Mojo/autograd.mojo:7:8: error: 'self.func_module' is uninitialized at the implicit return from this function
fn __init__(inout self, module_path: String):
^
/Users/anindyadeepsannigrahi/workspace/Mojo/autograd.mojo:7:23: note: 'self' declared here
fn __init__(inout self, module_path: String):
^
mojo: error: failed to run the pass manager
/Users/anindyadeepsannigrahi/workspace/Mojo/autograd.mojo:7:8: error: 'self.func_module' is uninitialized at the implicit return from this function
fn __init__(inout self, module_path: String):
^
/Users/anindyadeepsannigrahi/workspace/Mojo/autograd.mojo:7:23: note: 'self' declared here
fn __init__(inout self, module_path: String):
^
mojo: error: failed to run the pass manager
Ryulord
Ryulord3mo ago
the compiler needs to know with 100% certainty that self.func_module is initialized by the end of __init__ but it can't because it only gets initialized in your try block but not the except block. You'll need to give it some value in your except block or just get rid of the try-catch and make __init__ raise
Anindya
Anindya3mo ago
yes, I am thinking of not adding try block but then you saying just using a raise would work with an if?
Want results from more Discord servers?
Add your server