Thursday, January 17, 2008

هیچ وقت به این نکته فکر کردید که اگر زبان برنامه نویسی که از آن استفاده می کنید اعداد و عملگرهای اولیه روی اعداد رو پشتیبانی نمی کردند، چطور می تونستید از اون زبان استفاده کنید؟ اصلا، به نظر شما اگر یک زبان اعداد و عملگرهای لازم رو به صورت توکار پشتیبانی نکنه، راهی برای پیاده سازی اونها وجود داره؟ شاید جالب باشه اگر بدونید که در بسیاری از زبان های برنامه نویسی تابعی (Functional Programming Languages) این قابلیت وجود داره که بدون اینکه زبان شما از اعداد یا عملگر های اولیه پشتیبانی بکنه، به راحتی اونها رو با استفاده از توابع پیاده سازی بکنید ( هر چند به خاطر کارایی معمولا این کار انجام نمی شه). امروز داشتم به این موضوع فکر می کردم که میشه این کار رو در زبان های غیر تابعی هم انجام داد یا نه؟ سعی کردم اعداد طبیعی و عملگر جمع و تفریق رو با استفاده از زبان جاوا پیاده سازی کنم. این شد که می بینید. البته یک مقدار بد قیافه به نظر می رسه.

interface NaturalNum {

boolean isZero();

NaturalNum next();

NaturalNum prev();

NaturalNum add(NaturalNum n);

NaturalNum sub(NaturalNum n);

}

class Zero implements NaturalNum {

public static final Zero INSTANCE = new Zero();

private Zero() {}

public NaturalNum add(NaturalNum n) { return n; }

public boolean isZero() { return true; }

public NaturalNum next() { return new Successor(this); }

public NaturalNum prev() { throw new RuntimeException(); }

public NaturalNum sub(NaturalNum n) {

if(n.isZero()) return this;

else throw new RuntimeException();

}

public String toString() { return ""; }

}

class Successor implements NaturalNum {

private final NaturalNum p;

public Successor(NaturalNum n) { this.p = n; }

public NaturalNum add(NaturalNum n) { return this.prev().add(n.next()); }

public boolean isZero() { return false; }

public NaturalNum next() { return new Successor(this); }

public NaturalNum prev() { return p; }

public NaturalNum sub(NaturalNum n) {

return n.isZero() ? this : this.prev().sub(n.prev());

}

public String toString() { return prev() + "1"; }

}

public class NaturalNumberTest {

public static void main(String[] args) {

NaturalNum three = Zero.INSTANCE.next().next().next();

NaturalNum four = Zero.INSTANCE.next().next().next().next();

System.out.println(three);

System.out.println(four);

System.out.println(three.add(four));

System.out.println(four.sub(three));

}

}

3 comments:

Anonymous said...

fekr konam a'dade tabi'i (Natural Numbers) az adade yek shoro'e mishe, na az sefr!
vali dar kol poste jalebi bod...

Mohsen Momeni said...

برای تفریق اعدادی که اولی از دومی کوچکتر است، اشتباه کار می‌کند. یعنی پیش‌بینی نشده.

من آخرش نفهمیدم این next , prevِ برای اعداد غیرصفر چه جوری کار می‌کنه.
میشه یه کمی توضیح بدی؟

Mohsen said...

سلام محسن جان، چه خبر؟ از این طرفا؟
اعداد طبیعی شامل اعداد صحیح مثبت و احتمالا صفر می شود، اینجا را ببینید:
http://en.wikipedia.org/wiki/Natural_number
و همین طور که می دانید این مجموعه اعداد نسبت به عمل تفریق بسته نیست. به همین دلیل اگر عدد اول کوچکتر باشد نمی توان از عملگر تفریق این کلاس استفاده کرد.
طرز کار اعداد غیر صفر هم خیلی ساده هست، هر عدد غیر صفر n یک ارجاع p به عدد قبل از خود یعنی n-1 نگه می دارد.