Designing CSS Buttons: Techniques and Resources

http://www.smashingmagazine.com/

 

Buttons, whatever their purpose, are important design elements. They could be the end point of a Web form or a call to action. Designers have many reasons to style buttons, including to make them more attractive and to enhance usability. One of the most important reasons, though, is that standard buttons can easily be missed by users because they often look similar to elements in their operating system. Here, we present you several techniques and tutorials to help you learn how to style buttons using CSS. We’ll also address usability.

Links vs. buttons

Before we explain how to style buttons, let’s clear up a common misconception: buttons are not links. The main purpose of a link is to navigate between pages and views, whereas buttons allow you to perform an action (such as submit a form).

In one of his articles, Jakob Nielsen writes about command links, which are a blend of links and buttons. But he recommended that command links be limited to actions with minor consequences and to secondary commands. To learn more about primary and secondary commands (and actions), check out Primary and Secondary Actions in Web Forms by Luke Wroblewski. To learn more about the differences between links and buttons, read Creating Usable Links and Buttons at UXBooth.

Basic Styling

The simplest way to style links and buttons is to add background color, padding and borders. Below are examples of the code for the link, button and input (”Submit”) elements.

Sample button
<button class="button" id="save">Sample button</button>
<input class="button" value="Sample Button" type="submit" />
.button {
padding:5px;
background-color: #dcdcdc;
border: 1px solid #666;
color:#000;
text-decoration:none;
}

This simple code minimizes the visual differences between links and buttons. And here are the rendered examples of the code above:

Different Buttons in Designing CSS Buttons: Techniques and Resources

The important thing to note is that these three elements render differently with the same CSS. So, you should style these elements carefully to ensure consistency across your website or application.

Images

Adding images to buttons can make the buttons more obvious. Sometimes the image itself clearly communicates the purpose of a button; e.g. a loupe icon for searching or a floppy disk icon for saving. The easiest way to add an image to a button is to use a background image and then position it accordingly. Below are our examples with a checkmark icon.

.button {
padding: 5px 5px 5px 25px;
border: 1px solid #666;
color:#000;
text-decoration:none;
background: #dcdcdc url(icon.png) no-repeat scroll 5px center;
}

Different Buttons2 in Designing CSS Buttons: Techniques and Resources

Button States

In addition to their default state, buttons and links can have two other states: hover and active (i.e. pressed). It is important that buttons appear different in different states so that users are clear about what is happening. Any element in a hover state can be styled by invoking the :hover CSS pseudo-class.

a:hover {
color:#f00;
}

Though very important, the active state is rarely implemented on websites. By showing this state, you ensure that your buttons are responsive and send a visual cue to users that a button has been pressed. This is called isomorphic correspondence, and it is “the relationship between the appearance of a visual form and a comparable human behavior” (Luke Wroblewski, Site-Seeing). The article Pressed Button State With CSS elaborates on the importance of the active state.

a:active {
color:#f00;
}

There is yet one more state, one that is seen when navigating with the keyboard: the focus state. When the user navigates to a button using the Tab key, it should change appearance, preferably to have the same appearance as the hover state.

a:focus {
color:#f00;
}

The examples below shows the common way to style button states. The hover state is a bit lighter than the normal state, while the active state has an inverted gradient that simulates a pressed action. Although you need not limit yourself to this styling, it is a good place to start.

Button States in Designing CSS Buttons: Techniques and Resources

We should talk about how to handle the outline property for the :active and :focus states. Handling this property well is important for the experience of users who employ the keyboard as well as the mouse. In the article Better CSS Outline Suppression,” Patrick Lauke shows how buttons and links behave in different combinations of states and explains why the outline property should be invoked only with the :active state.

Apple in Designing CSS Buttons: Techniques and Resources

The blue “Buy now” button on Apple.com has a slightly lighter background for the hover state and an inset style for active state. Even the main navigation button on Apple’s website implements all three states.

Tearoundapp in Designing CSS Buttons: Techniques and Resources

Although it doesn’t implement the active state, this fancy button on Tea Round has a nice fading effect on hover.

Uxbooth Button in Designing CSS Buttons: Techniques and Resources

The “Read more” button on UX Booth turns green on hover and moves down one pixel in the active state, which simulates the effect of pressing a button.

Useful Reading

The article Rediscovering the Button Element shows the differences between links and buttons and explains how to style buttons easily.

Rediscover Button in Designing CSS Buttons: Techniques and Resources

Styling Form Buttons covers the basics of styling buttons, with many examples.

Tyssendesign in Designing CSS Buttons: Techniques and Resources

Beautiful CSS Buttons With Icon Set shows how to style buttons using background images. Although not scalable, these are really nice buttons.

Buttonnice in Designing CSS Buttons: Techniques and Resources

Recreating the Button is a very good article that explains how Google ended up with the buttons that it uses on majority of its websites.

Stopdesign in Designing CSS Buttons: Techniques and Resources

Scalable CSS Buttons Using PNG and Background Colors explains how to create really stunning buttons for all states. Although it uses jQuery, it degrades gracefully if JavaScript is turned off.

Monc in Designing CSS Buttons: Techniques and Resources

Sliding Doors: Flexible Buttons

One important consideration needs to be made when styling buttons: scalability. Scalability in this context means being able to stretch a button to fit text and to reuse images. Unless you want to create a different image for each button, consider the “sliding doors” technique. This technique enables you to create scalable, rich buttons.

Sliding Doors in Designing CSS Buttons: Techniques and Resources

The principle involves making two images slide over each other, allowing the button to stretch to the content. Usually, this is done by nesting a span element within a link. As shown in the image above, each element has its own background image, allowing for the sliding effect. The two code snippets below show the structure and basic styling for this effect.

Typical sliding doors button
a {
background: transparent url('button_right.png') no-repeat scroll top right;
display: block;
float: left;
/* padding, margins and other styles here */
}
a span {
background: transparent url('button_left.png') no-repeat;
display: block;
/* padding, margins and other styles here */
}

The advantages of this technique are that it:

  • Is an easy way to create visually rich buttons;
  • Ensures accessibility, flexibility and scalability;
  • Requires no JavaScript;
  • Works in all major browsers.

Useful Reading

The “Sliding Doors of CSS” article on A List Apart (part 1 and part 2) covers the basics of this technique. Although a bit old, these articles are a must-read for every Web developer.

Alistapart in Designing CSS Buttons: Techniques and Resources

Also a bit old, Creating Bulletproof Graphic Link Buttons With CSS is an excellent article that shows how to create bulletproof, resizable, shrunk-wrap buttons. Also a must-read.

456bereast in Designing CSS Buttons: Techniques and Resources

Filament Group has a variety of excellent articles and tutorials. Its second article on CSS buttons, Styling the Button Element With CSS Sliding Doors,” explains how to create buttons by combining techniques. Although it doesn’t support the active state, it can be easily extended.

Filament in Designing CSS Buttons: Techniques and Resources

How to Make Sexy Buttons With CSS is one of the best and simplest explanations of the sliding doors technique. It also contains a little fix for the active state in Internet Explorer.

Oscaralexander in Designing CSS Buttons: Techniques and Resources

If you want Wii-like buttons, the article Simple Round CSS Links (Wii Buttons) provides all the necessary resources and explanation on how to style them.

Wii in Designing CSS Buttons: Techniques and Resources

The common way to achieve the CSS sliding doors technique is to use two images. However, the article CSS Sliding Door Using Only One Image shows that it is possible to achieve the same effect with only one image.

Kailoon in Designing CSS Buttons: Techniques and Resources

CSS Oval Buttons and CSS Square Buttons from Dynamic Drive are two other articles that show the effectiveness of CSS sliding doors.

Dynamicdrive in Designing CSS Buttons: Techniques and Resources

CSS Sprites: One Image, Not Many

With CSS Sprites, one image file contains multiple graphic elements, usually laid out in a grid. By tiling the image, we show only one Sprite at a time. For buttons, we can include graphics for all three states in a single file. This technique is efficient because it requires fewer resources and the page loads faster. We all know that many requests to the server for multiple small resources can take a long time. This is why CSS Sprites are so handy. They significantly reduces round-trips to the server. They are so powerful that some developers use CSS Sprites for all their graphics. The Holy Sprites round-up on CSS Tricks offers some very creative solutions.

The example below shows the simplest use of CSS Sprites. A single image contains graphics for all three button states. By adjusting the background-position property, we define the exact position of the background image we want. The image we’re choosing to show here corresponds to a background position of top: -30px and left: 0.

Sprites in Designing CSS Buttons: Techniques and Resources

a {
background: white url(buttons.png) 0px 0px no-repeat;
}
a:hover {
background-position: -30px 0px;
}
a:active {
background-position: -60px 0px;
}

For general information and resources on CSS Sprites, check out The Mystery of CSS Sprites: Techniques, Tools and Tutorials.”

Useful Reading

In this easy-to-follow tutorial How to Build a Simple Button with CSS Image Sprites,” Chris Spooner explains how to create a CSS Sprites image in Photoshop and use it with CSS.

Line25 in Designing CSS Buttons: Techniques and Resources

Transforming the Button Element With Sliding Doors and Image Sprites shows how to enrich a button element with a combination of sliding doors and image Sprites. It implements the active state in a very interesting way, not by using different images or colors but rather by positioning.

CSS 3: Buttons Of The Future

CSS 3 allows us to create visually rich buttons with just a few lines of code. So far, this is the easiest way to create buttons. The downside of CSS 3 is that it is currently supported only by Firefox and Safari. The upside is that buttons styled with CSS 3 degrade gracefully in unsupported browsers. By using the browser-specific properties -moz-border-radius (for Firefox) or -webkit-border-radius (for Safari), you can define the radius of corners. Here are a few examples of what can be done with the border radius property.

Css3 Rounded in Designing CSS Buttons: Techniques and Resources

For better results, you can combine CSS 3 rounded corners with the background image property. The example below shows a typical button with a gradient image, the first without rounded corners, and the second with.

Rounded Corners in Designing CSS Buttons: Techniques and Resources

Compared to sliding doors, this technique is far simpler. However, if you want to maintain visual consistency across all browsers, then use sliding doors, because it works in all major browsers, including IE6. To learn more about the capabilities of CSS 3, read CSS 3 Exciting Functions and Features: 30+ Useful Tutorials.” And here are a few good tutorials on styling buttons with CSS 3 features.

Useful Reading

Super Awesome Buttons With CSS 3 and RGBA shows the power of CSS 3 with rounded corners, Mozilla box shadows and RGBA, which is a color mode that adds alpha-blending to your favorite CSS properties. This is one of the best examples of CSS 3 buttons.

Zurb in Designing CSS Buttons: Techniques and Resources

Create a CSS 3 Button That Degrades Nicely is a good example of CSS 3 buttons that degrade gracefully in browsers that don’t support CSS 3.

Stylizedweb in Designing CSS Buttons: Techniques and Resources

Creating buttons without Images Using CSS 3 explains the drawbacks of using images for buttons and shows several options for creating image-less CSS 3 buttons.

Opera in Designing CSS Buttons: Techniques and Resources

Emulating Google-Syle Buttons Using CSS 3 & dd_roundies JS is a fantastic article that shows how to create Google-like buttons. It goes even further and shows how to create the button pillbox commonly seen on Google pages.

Instant Tools: Are They Useful?

Tools exist for creating buttons, such as Easy Button and Menu Maker and My Cool Button, and for creating CSS Sprites, such as CSS Sprite Generator, but the question is, do they really help you create buttons that fit your needs. Although they are configurable and easy to use, your creativity and control over the results are limited, which makes for average-looking buttons. Using one-size-fits-all buttons is not a good idea.

The solution is to use Photoshop (or a free alternative) and the proven techniques described in this article. If you are a beginner with Photoshop, here are several excellent tutorials on creating amazing buttons.

If you don’t know where to start, iPhone-Like Button in Photoshop is the perfect choice. In only 10 to 15 minutes, you will be able to create the kind of buttons seen on the iPhone.

Iphone Button in Designing CSS Buttons: Techniques and Resources

How to Create a Slick and Clean Button in Photoshop is a very detailed tutorial that guides you through 30 simple steps and helps you learn the Photoshop basics. In addition, the article explains how to use these graphics in combination with HTML and CSS to create fully functional CSS buttons.

Sixrevisions in Designing CSS Buttons: Techniques and Resources

Photoshop Button Maker is a fantastic tutorial from PSD Tuts that shows how to create fancy oval buttons (or badges).

Psdtuts in Designing CSS Buttons: Techniques and Resources

Buttons And Usability: Instead Of Conclusion

The techniques described above can help you create stunning buttons. However, because they play a critical role in website usability, the buttons should meet some key principles:

  1. First consider the labeling. Always label buttons with the name of the action that the user is performing. And always make it a verb. A common mistake is to label buttons “Go” for various actions such as searching, sending email and saving. Labels should also be short and to the point; no need to clutter the user interface.
  2. As mentioned, include all button states (default, hover, active) to provide clear visual cues to the user as to what is happening. Button outlines should remain in the active state only.
  3. Clearly distinguish between primary and secondary actions. The most important action should be the most prominent. This is usually done by giving primary and secondary actions different colors.
  4. Pay close attention to consistency. Buttons should be consistent throughout a Web application, both visually and behavior-wise. Use CSS sliding doors for reused buttons or CSS 3 rounded corners to maintain consistency.
  5. Though obvious, we should note that the entire button area should be clickable.

The articles below provide even more usability guidelines and best practices for designing buttons.

Make Complete Button Surface Active and Enhance Usability is an in-depth article that shows mistakes in button design and that explains why the entire button surface should be clickable.

Uxpassion in Designing CSS Buttons: Techniques and Resources

Creating Usable Links and Buttons explains why users expect buttons sometimes and links other times. It also shows how to choose between the two elements.

Uxbooth in Designing CSS Buttons: Techniques and Resources

How to Design Buttons to Help Improve Usability explains some usability principles that should be considered when designing buttons. It covers the basics of icon usage, appearance, behavior, hierarchy and consistency.

(al)

Loading mentions Retweet
Filed under  //  apps   pgm   software   technology  
Comments (0)
Posted 18 days ago

The PHP Easy Start Guide

Lately, there have been several people asking "What is the best way to learn PHP?", and while we don't mind helping you, it is starting to become a little repetitive.

First thing first, PHP is NOT easy to master, however it is easy to learn. The difference is that in NO way will you be making an online game in PHP as soon as you start learning it. Games are incredibly complex, and take a lot of time, work, and determination to finish. I have Started about five games, and only one of them is up and still being worked on.

1. Hosting


Before everything else, if you really want to learn PHP, you will learn it by doing. Fist off, you will need some type of hosting.

1.1 Free Hosting


As there is plenty of free hosting out there, That may be the way to go, and it has several advantages and disadvantages.

Advantages:

  • It's Free
  • It's accessible from the Web, meaning people can help you, see error pages that occur, Etc.
  • No need to use up Disk Space on your computer for something such as WAMP (detailed later on)


Disadvantages

:
  • Most of the sites usually have great restrictions (IE: possible advertising, irremovable footers, HUGE limits on BandWidth)
  • If the server encounters a problem, don't expect a letter to them to do anything. They offer it to you free, and therefore don't "need" to keep it up for you.


Links:
Freehostia
Geocities
Listings

1.2 Dedicated Server

Advantages

  • Servers usually have 99.9% uptime guaranteed (meaning they will reimburse you if they're down too long)
  • PHP and MySQL are usually included in the package
  • If something happens, chances are they are already at work fixing it for you

Disadvantages

  • Costs to host (though generally cheap)

 

1.3 Local Machine Server


Yes, it IS possible to install Apache, PHP, and MySQL onto your PC, regardless of if it is Linux, Windows, or other.

Advantages:

  • You can control all of the options of PHP, MySQL, AND Apache, involving things such as Mod-Rewrite
  • No external provider to deal with
  • 100% uptime when you need it, All you need to do is turn it on, and it works if you installed it correctly
  • Free


Disadvantages:

  • Uses internal Disk Space (not a lot, but enough to mention)
  • Large operations may take a while to work with, as it is limited by your CPU and RAM (though generally not a BIG disadvantage, it does occur sometimes on very intense calculations)


Links:
WAMP
XAMPP

1.4 PHPDock


PHPDock is generally overlooked, as I don't think many people know about it. It enables you to build a PHP website, and deploy it with NO internet connection required.

Advantages:

  • Used on your general machine
  • Can create Desktop Applications in PHP


Disadvantages:

  • Expensive ($149)
  • Usually only works well with NuSphere PHPED
  • You're forced to use Internet Explorer to view them


Links:
NuSphere PHPDock

2. Learning


Learning PHP is a delicate process. What you learn, and the way you learn it, influences how you code. That is why it is crucial that you learn it correctly. My suggestion is to go with W3Schools AND Tizag (yes, I said read both).

2.1 W3Schools


W3Schools is where I learned PHP. I still use it when i forget a function or need to look it up. It has a plain basic interface, nothing special, but the knowledge it contains is very helpful, and will lead you towards the right path to programming.

Link:
W3Schools

2.2 Tizag


Tizag is one of the favorites here at DIC, and provides very in-depth, easy to understand tutorials. Their no-frills website has several things about PHP that will help you in the long run.

Link:
Tizag

2.3 Others


There are several PHP learning sites out there. Zend is the company that offers the Send PHP Certification, something you may become interested in getting if your job requires it. LearnPHP.org Has several tutorials that I don't even think DIC has. They go in-depth to several CMS (Content Management Systems), something you may find useful. About.com is another good site for learning, and offers some well written tutorials.

3. PHP Editors


Ok, so now that you have something that can run PHP, and you have begun learning it, the next step is programming it.

3.1 Integrated Development Environment

Advantages:

  • Shows errors in the code along with readable error codes
  • Installs PHP onto your machine
  • Applications can be tested by hitting a "run" command
  • Usually show complete error messages on the run tab (IE: Error and Line on which the error occured)


Disadvantages:

  • Expensive. NuSphere PHPED costs $495.00 for the professional version, and if you're just starting, you might not want to spend any money at all.


Links:
NuSphere PHPED
PHP Designer
PHP Edit

3.2 Notepad


Yes, Notepad can make PHP Files! All you need to do is save it as .php.

Advantages:

  • Free
  • Already installed on your system (for Windows Users. For Mac and other users, there should be a similar program)


Disadvantages:

  • No error handling
  • No Debugging
  • Manually have to indent/align your code
  • No highlighting or code Folding


3.3 Notepad++


Notepad++ is a completely Free PHP Editor. It offer code highlighting and folding, as well as editors for several languages.

Advantages:

  • Free
  • Small Size
  • has a VERY large list of Plugins to increase functionality


Disadvantages:

  • There are a few bugs, but they're few and far between

 

4. Other Reading


DIC Has several things that you should read if you want to learn php.

4.1 The giant PHP List of Common Problems
I created The giant PHP List of Common Problems to help people with their problems. Most that occur are simple issues, such as wrong Logic, and problems with things such as Headers and Sessions.

Link:
The giant PHP List of Common Problems

4.2 PHP Tutorials
DIC Has several tutorials in their tutorial section built specifically to help you understand PHP. They have basic ones (such as simple login scripts) to more advanced ones (like building a complete CMS).

Link:
PHP Tutorials

4.3 How to get better help on DIC
"How to get better help on DIC" is a guide written by Akozlik. It details common problems that occur when posting on DIC, and how to request the help that you actually need. Many people don't clearly state what it is they need help with, and we shouldn't be expected to read through your entire code looking for errors that we don't know exist.

Link:
How to get better help on DIC

4.4 The PHP Forum
If you need help, don't be afraid to ask! We're here to help you, so long as you help us help you. No cryptic messages, your best English (though we understand not everyone speaks perfect English, and many have it as a second language), and Provide your Code.

DIC Is here to help you help yourself, not to hand everything to you.

Link:
PHP Forum

 

Loading mentions Retweet
Filed under  //  pgm   php   software   technology  
Comments (0)
Posted 2 months ago

10+ extremely useful PHP classes

via:  http://www.catswhocode.com/blog/10-extremely-useful-php-classes

PHP PSD Reader

A few weeks ago, I wrote an article about this PHP which allow you to display any Adobe PSD file on screen. Very usefull to create preview of PSDs designed for clients, for example.
Download

Browser detect

One of the most common (and boring) problem for front-end developers is definitely cross-browser compatibility. This PHP class will detect almost all browsers and simplify your cross-browser work.
Download

Akismet

Remember those days without spam? If your website gets spammed in any ways, Akismet can probably help you. When a new comment, trackback, or pingback comes to your site it is submitted to the Akismet web service which runs hundreds of tests on the comment and returns a thumbs up or thumbs down.
Download

ADOdb

The large majority of websites and web apps are using databases to store all kinds of data. ADOdb is a database abstraction library for PHP, supporting MySQL, PostgreSQL, Interbase, Firebird, Oracle, MS SQL and more. ADOdb is quite easy to learn and have lots of nice features as such as extensive portability support, speed and BSD licencing.
Download

HTML Purifier

As it name tells, HTML Purifier is a PHP class created to help you writing a better code. HTML Purifier can remove malicious code and make sure your code is standard-compliant. A great tool for all developers.
Download

Google charts API

Charts are very useful and highly asked by clients, but they can be a lot of work. I remember some years ago when a friend of mine had to create charts using Photoshop every week for one of his clients. Well, this time is gone for good.
With the Google charts API, a simple chart can be created and displayed on screen using as little as 4 lines of code.
Download

pChart

pChart is another chart class, and it is as good as Google charts API. Data can be easily retrieved from SQL queries, CSV files, or manually provided.
Download

PHP Excel

Excel documents are highly popular in the corporate world. Considering that fact, there's a strong chance that one of your clients asks for you to create excel files in PHP someday.
Happilly, the PHP Excel engine allow you to easily create and manipulate lots of different files, as such as Excel 2007, Open XML, or PDF.
Download

Country from IP

Some websites are able to detect your location and automatically display information related with your language. How do they do that? Quite simple, they use your IP adress to find your location. The Country from IP class is easy to use and will allow you to get the country a specific IP is from.
Download

Cache Manager

If you're working on a high traffic site, there's not doubt you'll need to cache files in order to improve performance. This will be very easy an simple to do, using this very handy class. A defifinitive must-have, in my opinion.
Download

WPGet

As I know many of you have a WordPress blog, I just can't finish this article without a great tool for our favorite blogging engine.
WPGet is a PHP class which allow you to easily get infos from a WordPress 2.X database. In other words, it allows you to get posts, comments, etc from a WordPress blog, on a non-WordPress site. Great, isn't it?
Download

Loading mentions Retweet
Filed under  //  pgm   php  
Comments (0)
Posted 2 months ago

Expert Web Site Optimization Secrets

via:http://w3-markup.com/ this is the site i got a info of creating the website opsy and its shhh.... secrets

Ok, so maybe secrets is a bit superlative in this case, nevertheless, several of the topics touched on in this post remain a mystery to many clients and professionals alike, so we thought we should expose some keys to well-performing web sites in more detail. Before we begin, let’s address the first possible question of “who cares?” Well yes it’s true that almost everyone has broadband and even the new iPhone will be pretty speedy on the web, what will always be true is that users don’t like to wait. In fact, what we can be sure of is that as devices become faster, a user’s patience will dramatically decrease. So to fight the attrition (user’s becoming so frustrated with a site’s performance that they never return), often caused by slow web site performance, we must always keep web site optimization in the back of our minds. After all, nothing kills a killer app’ faster than slow performance.

There have always been great tools and resources that help web developers and the like improve the user experience of their sites by following some best practices. However, what are often difficult to come by are some specific techniques that not only satisfy the requirements of the best practices, but also address issues that are even more circumstantial. In other words, we’re going to share some techniques that resolve nearly all of the most significant performance issues that web sites and web applications can face.

Understand first how your page(s) load by using Firebug for FireFox 2+ or IEInspector for Internet Explorer 5+. For those interested in Safari, you should check out this post from the webkit (Safari) team. It’s straight forward to find the area within either plug-in that allows you to observe the HTTP transactions and understand the behavior of your page from a transactional standpoint. We recommend using Firebug because it’s free; however using the IEInspector will allow you to see the page render behavior differences between IE and FF. Some relevant issues that impact performance that we’re not going to address in this post are:

  • Rendering performance — how does your markup and style sheet actually behave as the browser renders it and how does that impact the perceived speed of the page from a user’s perspective.
  • Database latency or page parse time — Dynamically generated pages or assets called in a page, like using PHP for server side includes or generating a table of data from a database entries play a role in the performance of a web site and we’ll set those issues aside for now and assume that you’ve optimized these factors as far as you can using server-side script caching, database caching etc.
  • External objects — that is objects that are not locally hosted on your domain like Google Analytics for example. Fortunately they do compress their JavaScript for us, no doubt using some of the techniques discussed later in this post.

As Aaron Hopkins said: “Try benchmarking common pages on your site from a local network with ab, which comes with the Apache web server. If your server is taking longer than 5 or 10 milliseconds to generate a page, you should make sure you have a good understanding of where it is spending its time.” We’re also going to assume that you’ve moved beyond the use of inline JavaScript and CSS; there are countless references and ongoing debates out there on how to deal with functionality semantics and presentational issues. Now there are some questions that need to be answered in order for you to proceed with effective use of the browser plug-ins we recommended:

  • Who is your target audience and what are the limitations of their browsing environments?
  • How much data would your server end up having to deliver if it was answering requests of thousands of concurrent users?
  • Aside from the actual “horsepower” of your web server and the quality/limitations of your server’s bandwidth, what are the things that you can change about your site that will realize the biggest impact? In other words, let’s apply the 80/20 rule.

The following concepts satisfy nearly any conceivable answer to the questions above:

  1. Reduce file sizes of assets and reuse them as much as possible
    Obviously this is the most simple of steps, and includes optimizing file sizes of: images, JavaScript files, CSS files, the HTML itself and so on. We won’t get into the techniques to optimize all of these because that’s a Pandora’s Box to be certain. Firebug’s “Net” tab will show you the weight (size) of all of the objects required to render the page you loaded. Take steps to reduce these as much as you can. Some concepts like: using strict DTDs, removing comments from your code, white space removal and the like to reduce file size are nice, but as you will find out for yourself are not pivotal to achieve the desired results. Again, remember the 80/20 rule, we want to improve our user experience without destroying our ability to maintain the site or make it accessible to as many user agents as possible. So instead of modifying your development process, take advantage of sound techniques as they relate to your CSS or JavaScript coding. Organize (and configure) your content to be cached. Which means avoid using: query string variables whenever possible, dynamically generated assets (images, CSS, JavaScript, markup etc), unless you mean to send the headers to the browser to force caching of your assets. Caching is definitely an imperative if your site uses query string variables or has other obvious issues that indicate to the browser that a document (page) should not be cached. Again we’ll leave that issue to another discussion since there are numerous solutions to that issue. Firebug will allow you to observe the headers of objects that are downloaded to review the headers associated with each object to make sure you’re getting the desired result. I’d encourage you to make sure you disable the browser cache (and any other non-essential plug-ins for that matter) using the Web Developer toolbar throughout your testing.
  2. Optimize HTTP transactions
    Now that file size is reduced and you’re confident that assets you desire to be cached are cached, endeavor to reduce the number of HTTP transactions. Again go back to the “Net” tab in Firebug and pay attention in particular to the number of transaction required to generate the entire page. From an image standpoint intelligent use of the sprites technique lends itself to image reuse, caching and optimized http transactions (a few larger files, rather than many small ones). As far as CSS, JavaScript are concerned, concatenate these files to further reduce HTTP transactions.
  3. Further reduce the size of text-based assets
    Let’s explore the benefits of HTTP compression. Many (at least more than in past years) web hosts support this “out-of-the-box” for the HTML MIME type. Server load aside, unfortunately compression of .html is simply not enough for high traffic sites that are not putting all of their CSS and JavaScript directly into their HTML documents (we don’t recommend optimization technique this for countless reasons). The effects of applying HTTP compression to a site is night and day, but unfortunately the leverage of this approach needs to be applied to all text based objects/assets required to render a page.In fact, HTTP compression really makes your AJAX applications really perform, but if you really plan things out you should be able to cache some of your AJAX events.
  4. Reduce the number of files
    We’ve learned how to compress our text based assets to reduce their weight and we’ve learned how combining related assets allows us to continue to use CSS Frameworks and/or compartmentalize our JavaScript so that our development style or preferences don’t impact the user experience. Now let’s finalize this process by pre-compressing our static content. There are scripts out there that are easy to find that will save you some time in achieving this result, but let’s be clear once again about what we’re up to in this step. Having the server do the heavy lifting of compressing your assets on-the-fly is great, but it doesn’t really scale. By combining and storing the compress version of the concatenated CSS or JS file, what you’re doing is further optimizing the performance of your web server, because what it’s now able to do is send static content, the very thing that all web servers excel at. This tip is vital to reaching that happy place we promised, when we said we would alleviate the most painful issues of most sites.
  5. Put everything in its place
    Web development fundamentals teach you to compartmentalize your CSS and JavaScript for maintainability and caching benefits, however, where is the best location of these external objects in your document? Most would agree that CSS belongs in the <head> of the page and they’d be correct, as for JavaScript, we encourage you to put only that code that’s required for accessibility of your interface in the <head> and everything else can be placed just above </body> at the bottom of the document. In this way, your presentation file is downloaded and cached and used to render the page, meanwhile users with fast connections can begin interacting with the page while the heaviest JS code is last to load (and then cached). Combined with the tip above, this approach allows you to avoid making sacrifices to make rich user experiences.
  6. Scale to fit
    Revisiting the issue of scale, now from a different point of view, use of a Content Delivery Network (CDN) has become a much more accessible solution to this problem. Since the days when Akamai was seen as an innovator and the “only” solution the problem of insatiable demand for a sites content (or to overcome poor developmental practices), the CDN has been instrumental in reducing latency in delivering objects to users by providing multiple regional POPs for your assets. There are a number of other more affordable leverage points for content delivery, nothing against Akamai, but these other options put this powerful solution in the reach of more people. When your web applications simply are not performing as well as you would like during peak times per day a CDN allows you to offload the busy work of delivering static assets and focus your web server on the thinking. Obviously point #4 should not be skipped when moving to this solution as you’ll see more leverage than you can imagine when these solutions are combined, not to mention save a tremendous amount on bandwidth charges (~60% usually). Meanwhile users will feel like your site or application has more speed because most of the assets a given user will be downloaded will come from the closest possible point on the web.
  7. Throw some horses at it
    For more complicated situations, you can look at throwing more hardware at the problem when the previous items have all be addressed and implemented. Specifically I’m referring to the Amazon Computing Cloud. This tip deals more with the web server component of solutions, so we’ll just consider this a bonus tip for those of you looking to make some computationally intense applications. This is a phenomenal offering from Amazon (and there are even others to consider from them) to be able to instantly scale and access a tremendous a lot of computing resources on-the-fly. Services like BrowserCam come to mind for solutions like this one.

So let’s see how techniques 1-5 combine to take shape:

HTTP Compression Report
Click the image for a larger view

It’s hard to argue with results!

A bonus tip is to use YSlow to get even more from Firebug! We’ve achieved some great performance with our home page:

Firebug: Net View
Click the image for a larger view

But YSlow shows us where we can still improve:

Firebug: YSlow
Click the image for a larger view

Unfortunately YSlow doesn’t pick up on the pre-compressed content we send to users, we’ll have to play with our headers more to satisfy #3 and #4 at the same time no doubt. We will work on these things as we see the need; regardless the techniques we discuss (points 1-5) are demonstrated in the results shown in these screen shots. Many of you may be familiar with some classic tools like Andy King’s Web Page Analyzer are a great starting point for identifying some troublesome areas of your page, but in recent years yahoo’s developer network has really put in a single place the findings that we’ve uncovered ("the hard way") over the years. Unfortunately, as with this post, you’ll still have to develop your own solutions, nonetheless we’d recommend heading over to developer.yahoo.com, they’ve done a great job documenting best practices for creating optimal user experiences, including:

  • Reduce HTTP requests (as stated above)
  • Reduce DNS lookups
  • Avoid HTTP redirects
  • Make your AJAX cacheable
  • Post-load components
  • Pre-load components
  • Reduce the number of DOM elements
  • Split components across domains
  • Minimize the number of inline frames
  • Eliminate 404s (file not found errors)

For many sites and in most situations only a few of the above are of concern, but those of you out there with an older sites or applications may benefit from going through the pages of their content, server, cookie, CSS, JavaScript, mobile and image best practices. The only thing I should warn you about when delving into these best practices is that as with anything you can have too much of a good thing. So once again we suggest the 80/20 rule, do what’s required for the maximum gain. Nevertheless, Yahoo!’s developer network has grown into a great resource to say the least.

So tell us what you think, if you’re interested we can put together some examples for you and/or touch on server related optimization techniques as well.

Loading mentions Retweet
Filed under  //  computer   pgm   technology   website  
Comments (0)
Posted 2 months ago

Ubuntu Moblin Remix Developer Edition Available on Dell's Mini 10v

Ubuntu Moblin Remix Developer Edition for the Inspiron Mini 10v is here. As we shared at the Intel Developer Forum today, Dell and Canonical have worked closely to ensure good hardware/software compatibility, and seamless integration between Ubuntu and Moblin. For those not familiar, Moblin is an open source project, created by Intel and hosted by the Linux Foundation, focused on building a Linux-based platform optimized for mobile devices. It has a unique user interface focused on using the Internet, social networking activity, and media consumption, and is optimized for small screens. The Moblin project recently released version 2.0, which includes many new features such as the myzone home screen panel, aggregation of social networking content (such as Twitter, last.fm, and instant messaging), a web browser optimized for the user interface, a "zoomable" media player, and an updated connection manager with a new user interface.

For a bit more, watch this demo from Doug Anson:

Canonical, the company behind the Ubuntu Linux distribution, has combined the core Moblin Version 2.0 interface, libraries, and applications with the internals of Ubuntu Linux 9.04 to create a new Linux distribution, Ubuntu Moblin Remix. We have labeled this distribution as a "Developer Edition", as it is still a work in progress at this time. We are currently targeting developers, Linux enthusiasts, and early adopters who want to get an early look at the software and begin developing for Moblin, participating in the community, and using new technology.

Ubuntu Moblin Remix Developer Edition can be purchased factory-installed on an Inspiron Mini 10v on from www.dell.com/ubuntu. To download the Ubuntu Moblin Remix installation image, or for more information, please visit our Moblin wiki page

Ubuntu Moblin Remix Developer Edition on the Dell Mini 10v

Loading mentions Retweet
Filed under  //  dell   Idea   pgm  
Comments (0)
Posted 2 months ago

Creating an Atom feed in PHP

Brian M. Carey, Information Systems Consultant, Triangle Information Solutions


Summary:  Atom is an XML specification that identifies information contained in a Web site. Using Atom, Web developers produce feeds that enable other Web developers (or consumers who use feed readers) to quickly locate and view information of interest on a remote site. Think of it as a Web site's index, available to anyone who wants it. Using PHP, a popular language of choice for most host providers, a Web developer can easily produce an Atom feed that can then be made available to the various feed readers and other Web developers. The ultimate result is a state-of-the-art information solution that enables the Web content to reach a much wider audience.

 

What is Atom?

Atom, as it is used here, refers to an XML language that enables Web publishers to syndicate the content of their Web sites to various consumers. Using Atom, publishers are able to create a Web feed in a standardized format. This feed enables users to read the contents of the Web site with software known as a feed reader. It also enables other Web developers to publish the contents of the feed on their own Web sites.

Atom is by no means the only syndication standard in use today. RSS is another standardized format (also using XML) and predates Atom. In fact, Atom was created in response to certain limitations in RSS.

As a result, the Atom specification contains numerous advantages over RSS. Atom provides a means to define the format of the data being provided—for example, HTML, XHTML, and so on—whereas RSS does not. Atom, unlike RSS, supports internationalization with the xml:lang attribute. Atom also accepts more state-of-the-art (and standardized) date formatting, relying on Request for Comments (RFC) 3339 as opposed to RSS's RFC 822.

Why PHP with Atom?

PHP stands for PHP: Hypertext Processor. It might be the only acronym in the English language that, when expanded, still contains the original acronym. The historical significance here is that PHP originally stood for Personal Home Page.

PHP is a scripting language that produces dynamic, server-side content. It works harmoniously with HTML, and PHP code is frequently embedded within standard HTML Web pages to facilitate dynamic content.

PHP also works extremely well with MySQL, a database management system. Over the years of Web development, these two technologies have evolved together and worked side by side on countless occasions. This is almost certainly due to one undeniable, overarching rationale: They are both free.

In answer to the question at the top of this section, PHP gives developers the flexibility of producing dynamic content in an easy-to-read and easy-to-develop manner. The dynamic content is retrieved from a MySQL database. The output page (the feed) is coded using PHP so that it renders an XML output that conforms to the Atom specification.

Note that the explanations in this article were written assuming that you are familiar with the basics of MySQL and PHP. If you are not, see the links to introductory tutorials in the Resources section of this article.

Defining the business use case: Fishing reports

Your boss is in your office. He really likes the way that the company's Web site (fishinhole.com) is operating. The site currently markets and sells fishing tackle of all types to enthusiastic sport fishermen. The site also provides a forum for fishing reports, wherein said enthusiastic sport fishermen share their fish tales.

Your boss takes a seat (without asking) in a chair in your office and complains that the Web site isn't getting enough broad exposure. He wants to use the fishing reports section of the Web page to lure (pun intended) more enthusiastic sport fishermen to the Web site. He tells you that he wants you to make that section of the Web site a "one-stop shop" for sport fishing reports worldwide. This is essential to your ongoing success with fishinhole.com (or so he says). Your boss slurps his coffee, smiles, and walks out of your office with nothing else to say.

You lean back in your chair and get to thinking: What could give the fishing reports forum broader exposure? A moment later it comes to you: syndication! Instead of simply making the reports section available to users and shoppers at fishinhole.com, you can syndicate the forum so that people can read synopses of the fishing reports with their feed readers. Other Web developers might also include the syndication feed in their own Web pages. In either case, people would click on report titles of interest and be linked back to fishinhole.com, where you can expose them to a barrage of fishing tackle direct marketing. It's a great idea.

The database design

Long before your boss walked into your office, the database for the fishing reports forum was already designed. Recall that the fishing reports section of the Web page already exists. It simply hasn't been syndicated yet.

So what changes to the database do you need to make to syndicate its contents? None! That's one of the great things about syndication. In most cases, you can syndicate articles without changing your underlying schema or data model. This is because in most cases, you will syndicate articles, and articles almost always have the information that is required by the Atom specification.

Listing 1 shows the database model currently used by the fishing reports section of fishinhole.com. It also contains someINSERTs so that you have test data.

 

Listing 1. REPORTS table structure with INSERTs



CREATE TABLE IF NOT EXISTS `reports` (
  `ID` bigint(20) NOT NULL auto_increment,
  `AUTHOR` varchar(32) NOT NULL,
  `TITLE` varchar(64) NOT NULL,
  `SUBTITLE` varchar(128) NOT NULL,
  `CONTENT` varchar(2000) NOT NULL,
  `POSTED` datetime NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;


INSERT INTO `reports` (`id`, `author`, `title`, `subtitle`, `content`, `posted`) VALUES
(1, 'BigRed', 'Spanish Bite Looking Good!', 'Near the Cape!', 
'Trolled for 3 hours and limited out on Spanish Macks!  Watch out for the shallows 
near green can #4.', '2009-05-03 04:54:33'),
(2, 'JonBoy', 'Big Rock Report', 'Spring has sprung', 
'Caught several blackfins and mahi just outside of the Big Rock on Saturday.  
We were using flourescent squid teasers with ballyhoo for hookups.  
One Mahi weighed over 50#!', '2009-05-03 04:56:06'),
(3, 'Erasmus', 'Drum in the backwaters', 'The bite was hot!', 
'Loaded up against the marsh grass, boys.  Go get em.  I was using gulp 
with 1/4 ounce jigheads.', '2009-05-03 04:57:19'),
(4, 'ReelHooked', 'Speckled Trout In Old River', 'Limited out by noon', 
'They were schooling heavy in Old River.  They would eat anything we would 
throw at them.  Most were undersized, but we managed to keep some 
and had our fill by midday.', '2009-05-03 04:59:00');


If you are going to actually test the code presented in this article, you can do so by creating a MySQL database called fishinhole and executing the code from Listing 1 in that database.

The first column (ID) is the primary key of the table. Note that it uses the auto_increment specification so that every time a new row is inserted into the table, the ID column is populated with an increment of the previous row's ID column. This is similar to a sequence in an Oracle table.

The AUTHOR column simply specifies the user name of the person who posted the fishing report. This is the user's screen name, as opposed to the user's real first and last name (unless the user's real name is, in fact, the screen name).

The TITLE column is simply the title of the article. Likewise, the SUBTITLE is the subtitle of the article and is used in the Atom feed for the article synopsis.

The CONTENT column is the actual fishing report itself. Because the Atom feed produced here only includes a synopsis of the overall article (thus encouraging users to click the link and access the Web site), the content itself is not displayed in the Atom feed.

Finally, the POSTED column is a DATETIME column that stores the date that the article was posted on the Web site.

To keep things simple, I provide only a few articles (4). In a real-world situation, there would be thousands of these articles from hundreds of different authors.

The work commences

Now that you have the database design in place, it's time to code the PHP page so it produces an Atom feed. This article will walk you through the basics of creating a simple Atom feed, which you can test using PHP.

Please note that if you want to test the code you need access to a PHP processor. Most hosting solutions provide such access. You may also have access to one locally. Consult with the necessary system administrators or technical support staff to find out how you can execute PHP documents in your Web environment.

Accessing the database in PHP

Create a new PHP file called syndication.php. That's where you'll put your code.

As mentioned previously, PHP and MySQL have a rich history of working extremely well together. Some might go so far as to say they are married. But such judgments are not in the scope of this article.

Listing 2 provides a basic code snippet that enables you to access the MySQL database created with the code from Listing 1.


Listing 2. Accessing the MySQL database in PHP

$link = mysql_connect('localhost', 'admin', 'password')
    or die('Could not connect: ' . mysql_error());

mysql_select_db('fishinhole') or die('Could not select database');

$query = 'SELECT id,title,subtitle,author,posted 
     FROM reports order by posted desc limit 25';
;
$result = mysql_query($query) 
     or die('Query failed: ' . mysql_error());


That code actually covers quite a bit, so it's important to go over it step by step.

First comes the mysql_connect() function. You need to change the parameters according to the specifications of your own environment. The first parameter is the database host. In some cases, it will be just like Listing 2 (that is, localhost). In other cases it will be a remote host (for example, IP Address 10.92.2.1). It might also be an actual host name, assuming that you have Domain Name System (DNS) revolution (for example, mysql.myhost.com).

The second parameter is the name of the MySQL user who will access the database. You can use admin, as shown, only if that is a valid account within your own MySQL environment. Refer to the MySQL documentation to learn how to create accounts for a MySQL database. Keep in mind that the account used here must have read rights to the REPORTS database.

The third parameter is the user's password. This needs to match the password used for the user identified in the second parameter.

The or die clause is included to provide the developer with diagnostic information in the event of a failure. If a connection cannot be made to the database management system, you receive a message indicating that the connection failed and the reason it failed when the PHP script is executed.

Next comes the mysql_select_db() function. This is where you actually select which database you plan to use. Your own copy of MySQL can (and likely does) contain many databases, so it's important to specify which one you want to use.

Recall that I recommended you create a MySQL database called fishinhole if you want to test the functionality of the code provided in this article. The mysql_select_db() line specifies that you will use that database.

Next comes the actual query. In this case, you just define the query in a string. Here you grab the IDTITLESUBTITLEAUTHOR, and POSTED columns from the REPORTS table. The order by posted desc clause forces the query to return rows in descending order by the date in the POSTED column (which is the date that the article was posted on the Web site). So, you retrieve the most recent articles first. This is a standard practice for feeds.

The limit 25 clause at the end is important. This is where you specify that you want a maximum of 25 articles returned for this feed. Recall I mentioned earlier that forums such as this one can have thousands of articles. It is simply not practical to return thousands of articles in a feed. The bandwidth used is significant, and most consumers end up waiting for awhile.

This query is a string. It is assigned to a variable intuitively named $query.

In the mysql_query() function, you actually execute the query defined in the previous line. The results of that query are stored in the $result variable. Once again, the or die clause is in place for diagnostic purposes.

The loop and the Atom specification

Now that you have the data from the database, it's time to start displaying it in a format that conforms to the Atom specification. Because Atom is an XML language, the output of the PHP file is in XML format, as opposed to HTML format. If you intend to use a Web browser to display the output, just keep in mind that it will display differently depending upon your browser and version. To view the XML output, it's usually best to right-click on the output in a browser and select View Source. Then you will see the raw XML output.

Before displaying information about each article, it's important to include the preamble to the Atom feed. This is the section that identifies the output as an Atom feed and provides pertinent information about the feed, as shown in Listing 3.


Listing 3. The Atom preamble


<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom"> 
     <title>Fishing Reports</title> 
     <subtitle>The latest reports from fishinhole.com</subtitle>
     <link href="http://www.fishinhole.com/reports/syndication.php" rel="self"/> 
     <updated><?php echo date3339(); ?></updated>
     <author> 
          <name>NameOfYourBoss</name>
          <email>nameofyourboss@fishinhole.com</email>
     </author>
     <id>
     tag:fishinhole.com,2008:http://www.fishinhole.com/reports/syndication.php
     </id> 



You might immediately notice that the code in Listing 3 doesn't look like PHP. That's because most of it isn't. It's standardized output that requires little in the way of dynamic content.

The <feed> element identifies this XML document as an Atom feed. The namespace used to define the elements is provided as an attribute of the <feed> element. You also use the aforementioned xml:lang attribute to specify that this is a document written in English.

The <title> element specifies a title for the overall feed. Likewise, the <subtitle> element specifies a subtitle for the overall feed.

The <link> element specifies the URL of this syndication.php document. The address in the example works in the fictitious world that is described in this article, but in real life it does not. In reality, you can include a link that produces the output of this feed.

The <updated> element produces a timestamp (compliant with the RFC 3339 standard) that tells the consumer of this feed when it was last updated. In this case, since the feed will always be up to date because it retrieves the latest data from the database, you use the current timestamp. And you may notice that there is a little snippet of PHP code in this element. That is a custom-built PHP function that produces a timestamp in RFC 3339 format.

The <author> element defines the author of the overall feed. You'll be using your boss's name as the author because it was his idea.

Finally, the <id> element uniquely identifies the feed in an Internationalized Resource Identifier (IRI) format.

Listing 4 is the main loop that produces each entry in the Atom feed. The vast majority of the work for producing the feed is done here.

Listing 4. The loop

<?php
     $i = 0;
     while($row = mysql_fetch_array($result))
       {
          if ($i > 0) {
               echo "</entry>";
           }

           $articleDate = $row['posted'];
           $articleDateRfc3339 = date3339(strtotime($articleDate));
           echo "<entry>";
           echo "<title>";
           echo $row['title'];
           echo "</title>";
           echo "<link type='text/html' 
                    href='http://www.fishinhole.com/reports/report.php?
                    id=".$row['id']."'/>";
           echo "<id>";
           echo "tag:fishinhole.com,2008:http:
                    //www.fishinhole.com/reports/report.php?id=".$row['id'];
           echo "</id>";
           echo "<updated>";
           echo $articleDateRfc3339;
           echo "</updated>";
           echo "<author>";
           echo "<name>";
           echo $row['author'];
           echo "</name>";
           echo "</author>"; 
           echo "<summary>";
           echo $row['subtitle'];
           echo "</summary>";

           $i++;
     }			
?>


Once again, Listing 4 covers quite a bit of ground. First, is the while loop. Basically, this part of the code says, in English, "as long as there are rows in the table that haven't been included in the output yet, keep going." The current row in each iteration is stored in a PHP variable intuitively called $row.

Then the counter ($i) is checked. If the counter is more than 0, then that means this is at least the second iteration. In that case, it is necessary to close the previous iteration's <entry> element.

The next two lines retrieve the article date (from the POSTED column) and convert it to RFC 3339 format using the aforementioned function.

Next, the <entry> element is started. Following that is the <title> element, which is populated from the TITLE column in the current row.

The <link> element is unusual in that it doesn't contain any child text. Instead, the actual link is referenced as an attribute. This is part of the Atom standard. The link simply points the user to the URL where the user can read the entire article. Recall that this feed provides only a synopsis to the user.

The <id> element is similar to the one that was described previously. It uniquely identifies this element in IRI format. And, as before, it is constructed from the relevant URL.

The <updated> element contains the DATETIME value (in RFC 3339 format) from the POSTED column. Recall that the$articleDateRfc3339 variable for this document was populated earlier in this iteration.

Next comes the <author> element. This element, unlike the others (but like the <author> element in the preamble) has child elements. For this article, only one of those children is used: the author's name. The author's name is populated from theAUTHOR column of the current row.

The <summary> element contains the information gleaned from the SUBTITLE column of the current row.

Finally, the loop counter ($i) is incremented, and the loop continues.

That, in a nutshell, is the entire body of code associated with producing an Atom document from the REPORTS table. As you can see, it's not as complicated as it might seem at first.

Also, keep in mind that many elements in the Atom specification are not covered here. You can just as easily add those by following the same patterns I describe in this section of the code. For more information, see Resources.

Test it!

Now comes the fun part: testing!

Rather than retype (or copy and paste) everything you see in the code listings above, you can simply use the PHP file that is included in the Download section. Copy that file to a local directory and make the necessary database changes that I described earlier (user name, password, and host). Then copy it to a PHP file structure that has access to the database.

When you have the PHP file in the correct place, launch your browser and access your file as follows: http://your host/context/syndication.php.

As with any customized solution, you need to change the values in italics to match your specific environment.

As I stated previously, your results will vary depending upon which browser and version you use. Some of the more modern browsers detect that this is an Atom feed and display the results accordingly. Others display it in raw XML format. Still others might produce nothing because the document is not a standard HTML document.

If the browser does not display the raw XML, you can do so simply by right-clicking on the document and selecting View Source. After you do that, you should see something similar to Listing 5.


Listing 5. The output (abbreviated)


<?xml version='1.0' encoding='iso-8859-1' ?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>Fishing Reports</title>
  <subtitle>The latest reports from fishinhole.com</subtitle>
  <link href="http://www.fishinhole.com/reports" rel="self"/>
  <updated>2009-05-03T16:19:54-05:00</updated>
  <author>
   <name>NameOfYourBoss</name>
   <email>nameofyourboss@fishinhole.com</email>
  </author>
  <id>tag:fishinhole.com,2008:http://www.fishinhole.com/reports</id>
  <entry>
   <title>Speckled Trout In Old River</title>
   <link type='text/html' href='http://www.fishinhole.com/reports/report.php?id=4'/>
   <id>tag:fishinhole.com,2008:http://www.fishinhole.com/reports/report.php?id=4</id>
   <updated>2009-05-03T04:59:00-05:00</updated>
   <author>
    <name>ReelHooked</name>
   </author>
   <summary>Limited out by noon</summary>
  </entry>
...
</feed>


Another way to test it is to verify that the feed is valid. You can do that using one of the many Atom feed validators you can find in cyberspace. A good one to use is http://www.feedvalidator.org. That Web site validates feeds in Atom, RSS, and Keyhole Markup Language (KML) formats.

Business Results

Because you implement and deploy your Atom feed, thousands of new enthusiastic sport fishermen from around the world now have exposure to the fishing reports on your Web site. You are getting hundreds of incoming links from sport fishing sites that are embedding your Atom feed. Some enthusiastic sport fishermen are even using feed readers to view the reports on a daily basis.

Your boss pops back into your office after looking at the latest traffic reports. He is pleased with the additional visits and reports that unique visitors have increased by 10%. He gives you a thumbs up, slurps his coffee, and walks away.

Conclusion

The Atom specification is an ideal means of syndicating your Web content. Using PHP with MySQL, you can easily produce a Web feed that complies with the Atom standard and is always up to date because it reads directly from the database. The feed can then be read by a feed reader or embedded in other Web sites. The end result is broader exposure for your Web content, and that means more visitors and, most likely, an increase to your bottom line.

 

Loading mentions Retweet
Filed under  //  IBM   pgm   sql   website  
Comments (0)
Posted 4 months ago

IBM---> Dive deeper into cloud computing through WebSphere

IBM30 July 2009 | Volume 10, Issue 29 
developerWorks Weekly Edition
 

Welcome, developers!
 

Prepare your Linux system for the future of disk storage. Dive deeper into cloud computing through WebSphere. Put thousands of UNIX commands at your fingertips with the man reference system. This week,developerWorks shows you how to do all of this and more. Our top features list makes for some outstanding reading: 


And if you're looking for a more hands-on learning experience, why not join us for developerWorks Live! briefings? These instructor-led training sessions can get you up to speed on the latest technologies, help you move your software projects forward, and show you how to squeeze the most out of your IT investments. Briefings cover a wide range of topics, and we've got them scheduled in locations worldwide. Check our listingsto see if there's one coming to your neighborhood. (If your newsletter profile includes your location information, then you should see events listed for your area in the space below this intro.) 

Can't make it to one of our live events? No worries! Our virtual briefingsare the next best thing -- online training sessions that effectively simulate the classroom setting. By combining voice, video, data, and graphics, virtual briefings provide a structured learning environment where it's easy to interact with your instructors. Keep checking the schedule: If you miss an event, you can always catch the replay. (Now there's an option I could have used in college.... 8am is no time for calculus!) 

Until next time,
John Swanson and the developerWorks editorial team 


(P.S. I'll be on vacation next week, so look for the next issue of this newsletter on 13 August.) 

DEVELOPER RESOURCES

Spotlight

Top 10 tutorials and articles on developerWorks 

Webcast: From credit cards to gift registries -- Connect everything with Smart SOA (12 August) 

My developerWorks: Get to know Suma Shastry, QA lead and dW author 

WebSphere eXtreme Scale V7.0 development AMI now available on Amazon EC2 

Follow us: Get developerWorks updates on Twitter 

Join us for developerWorks Live! briefings

Downloads

Trial: Rational Service Tester for SOA Quality

From alphaWorks: CIM Repository Synchronization for Cloud Computing

Download, try, or buy

Additional Resources

IBM privacy policy 

IBM copyright and trademark information

 
 
 Developer events in your area
developerWorks Live! briefing in Boston: Eclipse -- Empowering the universal platform
Dive into some of the most important, feature-rich projects that the Eclipse community is developing. From multi-language support to plug-in development, Eclipse is capable of far more than just Java development. (12 August 2009, Waltham, MA)
Don't miss out -- register today! >
Workshop in Austin: Get started with IBM software on Amazon Web Services featuring WebSphere sMash and DB2
This workshop shows you how to create an Amazon EC2 account, how to configure Amazon machine instances with preloaded IBM middleware, how Amazon EC2 security works, and much more. (25 August 2009, Austin, TX)
Don't miss out -- register today! >
More
 AIX and UNIX
AIX and UNIX zone | AIX and UNIX tutorials | AIX and UNIX articles | AIX and UNIX forums
Speaking UNIX: Man oh man
UNIX has hundreds if not thousands of commands, and it's impossible to remember every option and nuance. Fortunately, you don't have to: man, UNIX's built-in online reference system, is man's best friend. 
Learn about man's best friend >
 alphaWorks
Update: IBM Performance Simulator for Linux on POWER
If you're a Linux on POWER user, this tool offers you a set of performance models for IBM's POWER processors. The latest update adds an AIX version. 
Download it now >
Update: Performance Analysis Tool for Java
Use this tool to automatically detect Java threads that consume unanticipated large amounts of system resources. Version 2.1 supports PHD-CSV 4.0 file format.
Download it now >
More
 Information Management
Information Mgmt zone | Articles | Tutorials | Reader favorites | Forums | Downloads
Integrate heterogeneous metadata
Explore usage scenarios for integrating metadata from IBM Cognos Business Intelligence and IBM InfoSphere Information Server.
Start integrating >
Run Oracle applications on DB2 9.7 for Linux, UNIX, and Windows
Get a high-level overview of what Oracle compatibility means in DB2 for Linux, UNIX, and Windows with new, out-of-the-box support for Oracle's SQL and PL/SQL dialects.
Enable your Oracle apps for DB2 >
Integrate Cognos products with IBM Support Assistant
Resolve your software issues more efficiently by following these step-by-step instructions for integrating IBM Cognos Diagnostic Tools with the IBM Support Assistant.
Get the assist >
IBM Certification Days: Save 50% on professional certification
Demonstrate your expertise to the community. IBM Certification Day events are taking place at various venues around the globe. Participants receive a 50% discount on all Information Management certification exams.
Check out the event schedule and pre-register >
Virtual tech briefing: Optim Development Studio 101 (20 August)
Confused about Data Studio, Data Studio Developer, and now Optim Development Studio? Get a tour of Optim Development Studio from a product expert and learn how Optim Development Studio extends the capabilities in Rational Application Developer to turbo-charge the development and optimization of data persistence layers. (20 August 2009)
Book your calendar for this free tech briefing >
2009 Customer Innovation Awards: Nomination deadline extended to 7 August
Have you submitted your nomination of an innovative Information Management solution? There's still time to check out the exciting new categories added this year, and nominate by the extended deadline of 7 August.
Submit your entry today >
Plan now to attend IBM Information On Demand 2009 Global Conference
Choose sessions across three dynamic programs: Technical Skill Building, Business Leadership, and Business Partner Development. Don't miss the key global conference for Information Management professionals. (25 - 29 October 2009, Las Vegas, NV, USA)
Register now for the best savings >
Virtual conference: Effective data management for smarter outcomes (19 August)
Hear Gartner VP Donald Feinberg talk about the IT challenges, key trends, and innovations shaping the data management marketplace; listen to a moderated panel of customers and partners who have incorporated innovative technologies; ask questions during the live Q&A session; and much more. (19 August 2009) 
Register now >
Enhance your DB2 skills at IDUG Europe
Take your career and organization to the next level. Join hundreds of your colleagues at IDUG 2009 - Europe, coming to Rome, Italy, 5 - 9 October 2009. This IDUG event is the premier conference dedicated to providing technical education and networking specifically for IBM DB2 professionals.
Register early and save >
 Java technology
Java technology zone | New to Java programming | Forums | Standards | Downloads | Tutorials
Evolutionary architecture and emergent design: Language, expressiveness, and design
In this first of a two-part article, Neal Ford discusses the intersection of expressiveness and patterns, demonstrating these concepts with both idiomatic patterns and formal design patterns.
Better design >
Transaction strategies: The High Performance strategy
Mark Richards wraps up his series with a strategy for high-performance applications. Your application can maintain fast processing times while still supporting some degree of data integrity and consistency -- but you need to be aware of the trade-offs involved. 
Get to know the trade-offs >
 Linux
Linux zone | Articles | Tutorials | Forums | Reader favorites | LPI exam prep
Make the most of large drives with GPT and Linux
With 2TB disks now readily available and larger drives right around the corner, MBR doesn't cut it anymore. It's time for forward-looking Linux users to get familiar with the GUID Partition Table standard.. 
When a lot still isn't enough >
Linux tip: Create a pixel ruler from the command line
Manipulating graphics through shell commands and scripts might seem a little odd, but it's a useful skill for handling repetitive tasks and large batch jobs. Get started by using Bash scripting, shell arithmetic, and ImageMagick to create a pixel ruler graphic. 
Graphics for admins >
 Lotus
Lotus zone | New to Lotus | Articles | Tutorials | Downloads | Forums
Lotus Domino 8.5 server performance, Part 3: Enterprise cluster mail performance
Lotus Domino 8.5 offers features aimed at reducing the total cost of ownership of the Lotus Domino mail server cluster infrastructure in a large enterprise. In this article, see how you can leverage these features incrementally to realize TCO benefits while upgrading to Lotus Domino 8.5. 
Reduce your costs >
Trial: IBM Mashup Center
Download a complimentary trial of IBM Mashup Center software, which provides an easy-to-use business mashup solution, supporting quick assembly of dynamic situational applications.
Download now >
Now available: Lotus Notes widgets for LinkedIn, TripIt
Using these new widgets for Lotus Notes, you can open LinkedIn and TripIt applications via single sign-on right from your familiar Lotus Notes desktop screen. Simplify your professional networking and travel management tasks.
Boost your productivity >
 Rational
tabletabletabletable

Loading mentions Retweet
Filed under  //  cloud computing   IBM   pgm   social networking   web2.0  
Comments (0)
Posted 4 months ago

A Library of Streams

 

Title

A Library of Streams

Author

Philip L. Bewig

Status

This SRFI is currently in ``final'' status. It is also deprecated and superseded by SRFI 41. To see an explanation of each status that a SRFI can hold, see here. To comment on this SRFI, please mail to srfi minus 40 at srfi dot schemers dot org. See instructions here to subscribe to the list. You can access the discussion via the archive of the mailing list. You can access post-finalization messages via the archive of the mailing list.

  • Received: 2003/02/03
  • Draft: 2003/02/03-2003/04/03
  • Revised: 2003/08/02
  • Revised: 2003/12/23
  • Final: 2004/08/22

    Abstract

    Along with higher-order functions, one of the hallmarks of functional programming is lazy evaluation. A primary manifestation of lazy evaluation is lazy lists, generally called streams by Scheme programmers, where evaluation of a list element is delayed until its value is needed.

    The literature on lazy evaluation distinguishes two styles of laziness, called even and odd. Odd style streams are ubiquitous among Scheme programs and can be easily encoded with the Scheme primitives delay and force defined in R5RS. However, the even style delays evaluation in a manner closer to that of traditional lazy languages such as Haskell and avoids an "off by one" error that is symptomatic of the odd style.

    This SRFI defines the stream data type in the even style, some essential procedures and syntax that operate on streams, and motivates our choice of the even style. A companion SRFI 41 Stream Library provides additional procedures and syntax which make for more convenient processing of streams and shows several examples of their use.

    Rationale

    Two of the defining characteristics of functional programming languages are higher-order functions, which provide a powerful tool to allow programmers to abstract data representations away from an underlying concrete implementation, and lazy evaluation, which allows programmers to modularize a program and recombine the pieces in useful ways. Scheme provides higher-order functions through its lambda keyword and lazy evaluation through its delay keyword. A primary manifestation of lazy evaluation is lazy lists, generally called streams by Scheme programmers, where evaluation of a list element is delayed until its value is needed. Streams can be used, among other things, to compute with infinities, conveniently process simulations, program with coroutines, and reduce the number of passes over data. This library defines a minimal set of functions and syntax for programming with streams.

    Scheme has a long tradition of computing with streams. The great computer science textbook Structure and Interpretation of Computer Programs, uses streams extensively. The example given in R5RS makes use of streams to integrate systems of differential equations using the method of Runge-Kutta. MIT Scheme, the original implementation of Scheme, provides streams natively. Scheme and the Art of Programming, discusses streams. Some Scheme-like languages also have traditions of using streams: Winston and Horn, in their classic Lisp textbook, discuss streams, and so does Larry Paulson in his text on ML. Streams are an important and useful data structure.

    Basically, a stream is much like a list, and can either be null or can consist of an object (the stream element) followed by another stream; the difference to a list is that elements aren't evaluated until they are accessed. All the streams mentioned above use the same underlying representation, with the null stream represented by '()and stream pairs constructed by (cons car (delay cdr)), which must be implemented as syntax. These streams are known as head-strict, because the head of the stream is always computed, whether or not it is needed.

    Streams are the central data type -- just as arrays are for most imperative languages and lists are for Lisp and Scheme -- for the "pure" functional languages Miranda and Haskell. But those streams are subtly different from the traditional Scheme streams of SICP et al. The difference is at the head of the stream, where Miranda and Haskell provide streams that are fully lazy, with even the head of the stream not computed until it is needed. We'll see in a moment the operational difference between the two types of streams.

    Philip Wadler, Walid Taha, and David MacQueen, in their paper "How to add laziness to a strict language without even being odd", describe how they added streams to the SML/NJ compiler. They discuss two kinds of streams: odd streams, as in SICP et al, and even streams, as in Haskell; the names odd and even refer to the parity of the number of constructors (delayconsnil) used to represent the stream. Here are the first two figures from their paper, rewritten in Scheme:

    ;;; FIGURE 1 -- ODD                 
    				    
    (define nil1 '())                   
    				    
    (define (nil1? strm)                
      (null? strm))                     
    				    
    (define-syntax cons1                
      (syntax-rules ()                  
        ((cons1 obj strm)               
          (cons obj (delay strm)))))    
    				    
    (define (car1 strm)                 
      (car strm))                       
    				    
    (define (cdr1 strm)                 
      (force (cdr strm)))               
    				    
    (define (map1 func strm)            
                                        
      (if (nil1? strm)                  
        nil1                            
        (cons1                          
          (func (car1 strm))            
          (map1 func (cdr1 strm)))))    
    				    
    (define (countdown1 n)              
                                        
      (cons1 n (countdown1 (- n 1))))   
    				    
    (define (cutoff1 n strm)            
      (cond                             
        ((zero? n) '())                 
        ((nil1? strm) '())              
        (else                           
          (cons                         
            (car1 strm)                 
            (cutoff1 (- n 1)             
                     (cdr1 strm))))))    
    
    ;;; FIGURE 2 -- EVEN
    
    (define nil2 (delay '()))
    
    (define (nil2? strm)
      (null? (force strm)))
    
    (define-syntax cons2
      (syntax-rules ()
        ((cons2 obj strm)
         (delay (cons obj strm)))))
    
    (define (car2 strm)
      (car (force strm)))
    
    (define (cdr2 strm)
      (cdr (force strm)))
    
    (define (map2 func strm)
      (delay (force
        (if (nil2? strm)
          nil2
          (cons2
            (func (car2 strm))
            (map2 func (cdr2 strm)))))))
    
    (define (countdown2 n)
      (delay (force
        (cons2 n (countdown2 (- n 1))))))
    
    (define (cutoff2 n strm)
      (cond
        ((zero? n) '())
        ((nil2? strm) '())
        (else
          (cons
            (car2 strm)
            (cutoff2 (- n 1)
                     (cdr2 strm))))))
    

    It is easy to see the operational difference between the two kinds of streams, using an example adapted from the paper:

    > (define (12div n) (/ 12 n))       
    > (cutoff1 4                        
        (map1 12div (countdown1 4)))    
    error: divide by zero               
    
    > (define (12div n) (/ 12 n))
    > (cutoff2 4
        (map2 12div (countdown2 4)))
    (3 4 6 12)
    

    The problem of odd streams is that they do too much work, having an "off-by-one" error that causes them to evaluate the next element of a stream before it is needed. Mostly that's just a minor leak of space and time, but if evaluating the next element causes an error, such as dividing by zero, it's a silly, unnecessary bug.

    It is instructive to look at the coding differences between odd and even streams. We expect the two constructors nil and cons to be different, and they are; the oddnil and cons return a strict list, but the even nil and cons return promises. Nil?car and cdr change to accomodate the underlying representation differences.Cutoff is identical in the two versions, because it doesn't return a stream.

    The subtle but critical difference is in map and countdown, the two functions that return streams. They are identical except for the (delay (force ...)) that wraps the return value in the even version. That looks odd, but is correct. It is tempting to just eliminate the (delay (force ...)), but that doesn't work, because, given a promise x, even though (delay (force x)) and x both evaluate to x when forced, their semantics are different, with x being evaluated and cached in one case but not the other. That evaluation is, of course, the same "off-by-one" error that caused the problem with odd streams. Note that (force (delay x)) is something different entirely, even though it looks much the same.

    Unfortunately, that (delay (force ...)) is a major notational inconvenience, because it means that the representation of streams can't be hidden inside a few primitives but must infect each function that returns a stream, making streams harder to use, harder to explain, and more prone to error. Wadler et al solve the notational inconvenience in their SML/NJ implementation by adding special syntax -- the keyword lazy -- within the compiler. Since Scheme allows syntax to be added via a macro, it doesn't require any compiler modifications to provide streams. Shown below is a Scheme implementation of Figure 1 to 3 from the paper, with the (delay (force ...)) hidden within stream-define, which is the syntax used to create a function that returns a stream:

    ;;; FIGURE 1 -- ODD      
    			 
    (define nil1             
      '())                   
    			 
    (define (nil1? strm)     
      (null? strm))          
    			 
    (define-syntax cons1     
      (syntax-rules ()       
        ((cons1 obj strm)    
          (cons              
            obj              
              (delay         
                strm)))))    
    			 
    (define (car1 strm)      
      (car strm))            
    			 
    (define (cdr1 strm)      
      (force (cdr strm)))    
    			 
                             
                             
                             
                             
                             
                             
                             
    			 
    (define (map1 func strm) 
                             
      (if (nil1? strm)       
        nil1                 
        (cons1               
          (func              
            (car1 strm))     
          (map1              
            func             
            (cdr1            
              strm)))))      
    			 
    (define (countdown1 n)   
                             
      (cons1                 
        n                    
        (countdown1          
          (- n 1))))         
    			 
    (define (cutoff1 n strm) 
      (cond                  
        ((zero? n) '())      
        ((nil1? strm) '())   
        (else                
          (cons              
            (car1 strm)      
            (cutoff1         
              (- n 1)        
              (cdr1          
                strm))))))   
    
    ;;; FIGURE 2 -- EVEN     
    			 
    (define nil2             
      (delay '()))           
    			 
    (define (nil2? strm)     
      (null? (force strm))   
    			 
    (define-syntax cons2     
      (syntax-rules ()       
        ((cons2 obj strm)    
          (delay             
            (cons            
              obj            
              strm)))))      
    			 
    (define (car2 strm)      
      (car (force strm)))    
    			 
    (define (cdr2 strm)      
      (cdr (force strm)))    
    			 
                             
                             
                             
                             
                             
                             
                             
    			 
    (define (map2 func strm) 
      (delay (force		 
        (if (nil2? strm)     
          nil2               
          (cons2             
            (func            
              (car2 strm))   
            (map2            
              func           
              (cdr2          
                strm)))))))  
    			 
    (define (countdown2 n)   
      (delay (force		 
        (cons2               
          n                  
          (countdown2        
            (- n 1))))))     
    			 
    (define (cutoff2 n strm) 
      (cond                  
        ((zero? n) '())      
        ((nil2? strm) '())   
        (else                
          (cons              
            (car2 strm)      
            (cutoff2         
              (- n 1)        
              (cdr2          
                strm))))))   
    
    ;;; FIGURE 3 -- EASY
    
    (define nil3
      (delay '()))
    
    (define (nil3? strm)
      (null? (force strm)))
    
    (define-syntax cons3
      (syntax-rules ()
        ((cons3 obj strm)
          (delay
            (cons
              obj
              strm)))))
    
    (define (car3 strm)
      (car (force strm)))
    
    (define (cdr3 strm)
      (cdr (force strm)))
    
    (define-syntax stream-define
     (syntax-rules ()
      ((stream-define (name args ...)
                      body0 body1 ...)
       (define (name args ...)
        (delay (force
         (begin body0 body1 ...)))))))
    
    (stream-define (map3 func strm)
    
      (if (nil3? strm)
        nil3
        (cons3
          (func
            (car3 strm))
          (map3
            func
            (cdr3
              strm)))))
    
    (stream-define (countdown3 n)
    
      (cons3
        n
        (countdown3
          (- n 1))))
    
    (define (cutoff3 n strm)
      (cond
        ((zero? n) '())
        ((nil3? strm) '())
        (else
          (cons
            (car3 strm)
            (cutoff3
              (- n 1)
              (cdr3
                strm))))))
    

    It is now easy to see the notational inconvenience of Figure 2, as the bodies of map1 and map3 are identical, as are countdown1 and countdown3. All of the inconvenience is hidden in the stream primitives, where it belongs, so functions that use the primitives won't be burdened. This means that users can just step up and use the library without any knowledge of how the primitives are implemented, and indeed the implementation of the primitives can change without affecting users of the primitives, which would not have been possible with the streams of Figure 2. With this implementation of streams, (cutoff3 4 (map3 12div (countdown3 4))) evaluates to (3 4 6 12), as it should.

    This library provides streams that are even, not odd. This decision overturns years of experience in the Scheme world, but follows the traditions of the "pure" functional languages such as Miranda and Haskell. The primary benefit is elimination of the "off-by-one" error that odd streams suffer. Of course, it is possible to use even streams to represent odd streams, as Wadler et al show in their Figure 4, so nothing is lost by choosing even streams as the default.

    Obviously, stream elements are evaluated when they are accessed, not when they are created; that's the definition of lazy. Additionally, stream elements must be evaluated only once, and the result cached in the event it is needed again; that's common practice in all languages that support streams. Following the rule of R5RS section 1.1 fourth paragraph, an implementation of streams is permitted to delete a stream element from the cache and reclaim the storage it occupies if it can prove that the stream element cannot possibly matter to any future computation.

    The fact that objects are permitted, but not required, to be reclaimed has a significant impact on streams. Consider for instance the following example, due to Joe Marshall. Stream-filter is a function that takes a predicate and a stream and returns a new stream containing only those elements of the original stream that pass the predicate; it can be simply defined as follows:

        (stream-define (stream-filter pred? strm)
          (cond ((stream-null? strm) strm)
                ((pred? (stream-car strm))
                  (stream-cons (stream-car strm)
                               (stream-filter pred? (stream-cdr strm))))
                (else (stream-filter pred? (stream-cdr strm)))))
    

    But this implementation of stream-filter has a problem:

        (define (times3 n)
          (stream-car
            (stream-cdr
              (stream-cdr
                (stream-cdr
                  (stream-cdr
                    (stream-filter
                      (lambda (x) (zero? (modulo x n)))
                      from0)))))))
    

    Called as (times3 5), the function evaluates to 15, as desired. But called as (times3 1000000), it churns the disk, creating closures and caching each result as it counts slowly to 3,000,000; on most Scheme systems, this function will run out of memory long before it computes an answer. A space leak occurs when there is a gap between elements that pass the predicate, because the naive definition hangs on to the head of the gap. Unfortunately, this space leak can be very hard to fix, depending on the underlying Scheme implementation, and solutions that work in one Scheme implementation may not work in another. And, since R5RS itself doesn't specify any safe-for-space requirements, this SRFI can't make any specific requirements either. Thus, this SRFI encourages native implementations of the streams described in this SRFI to "do the right thing" with respect to space consumption, and implement streams that are as safe-for-space as the rest of the implementation. Of course, if the stream is bound in a scope outside the stream-filter expression, there is nothing to be done except cache the elements as they are filtered.

    Although stream-define has been discussed as the basic stream abstraction, in fact it is the (delay (force ...)) mechanism that is the basis for everything else. In the spirit of Scheme minimality, the specification below gives stream-delay as the syntax for converting an expression to a stream; stream-delay is similar to delay, but returns a stream instead of a promise. Given stream-delay, it is easy to create stream-lambda, which returns a stream-valued function, and then stream-define, which binds a stream-valued function to a name. However, stream-lambda and stream-define are both library procedures, not fundamental to the use of streams, and are thus excluded from this SRFI.

    Specification

    A stream-pair is a data structure consisting of two fields called the stream-car and stream-cdr. Stream-pairs are created by the procedure stream-cons, and the stream-car and stream-cdr fields are accessed by the procedures stream-car and stream-cdr. There also exists a special stream object called stream-null, which is a single stream object with no elements, distinguishable from all other stream objects and, indeed, from all other objects of any type. The stream-cdr of a stream-pair must be either another stream-pair or stream-null.

    Stream-null and stream-pair are used to represent streams. A stream can be defined recursively as either stream-null or a stream-pair whose stream-cdr is a stream. The objects in the stream-car fields of successive stream-pairs of a stream are the elements of the stream. For example, a two-element stream is a stream-pair whose stream-car is the first element and whose stream-cdr is a stream-pair whose stream-car is the second element and whose stream-cdr is stream-null. A chain of stream-pairs ending with stream-null is finite and has a length that is computed as the number of elements in the stream, which is the same as the number of stream-pairs in the stream. A chain of stream-pairs not ending with stream-null is infinite and has undefined length.

    The way in which a stream can be infinite is that no element of the stream is evaluated until it is accessed. Thus, any initial prefix of the stream can be enumerated in finite time and space, but still the stream remains infinite. Stream elements are evaluated only once; once evaluated, the value of a stream element is saved so that the element will not be re-evaluated if it is accessed a second time. Streams and stream elements are never mutated; all functions involving streams are purely applicative. Errors are not required to be signalled, as in R5RS section 1.3.2, although implementations are encouraged to detect and report errors.

    stream-null (constant)
    Stream-null is the distinguished nil stream, a single Scheme object distinguishable from all other objects. If the last stream-pair in a stream contains stream-null in its cdr field, the stream is finite and has a computable length. However, there is no need for streams to terminate.
        stream-null                                 => (stream)
    
    (stream-cons object stream) (syntax)
    Stream-cons is the primitive constructor of streams, returning a stream with the given object in its car field and the given stream in its cdr field. The stream returned by stream-cons must be different (in the sense of eqv?) from every other Scheme object. The object may be of any type, and there is no requirement that successive elements of a stream be of the same type, although it is common for them to be. It is an error if the second argument of stream-cons is not a stream.
        (stream-cons 'a stream-null)                => (stream 'a)
        (stream-cons 'a (stream 'b 'c 'd))          => (stream 'a 'b 'c 'd)
        (stream-cons "a" (stream 'b 'c))            => (stream "a" 'b 'c)
        (stream-cons 'a 3)                          => error
        (stream-cons (stream 'a 'b) (stream 'c))    => (stream (stream 'a 'b) 'c)
    
    (stream? object) (function)
    Stream? returns #t if the object is a stream, and otherwise returns #f. A stream object may be either the null stream or a stream pair created by stream-cons.
        (stream? stream-null)                       => #t
        (stream? (stream-cons 'a stream-null))      => #t
        (stream? 3)                                 => #f
    
    (stream-null? object) (function)
    Stream-null? returns #t if the object is the distinguished nil stream, and otherwise returns #f
        (stream-null? stream-null)                  => #t
        (stream-null? (stream-cons 'a stream-null)) => #f
        (stream-null? 3)                            => #f
    
    (stream-pair? object) (function)
    Stream-pair? returns #t if the object is a stream pair created by stream-cons, and otherwise returns #f.
        (stream-pair? stream-null)                  => #f
        (stream-pair? (stream-cons 'a stream-null)) => #t
        (stream-pair? 3)                            => #f
    
    (stream-car stream) (function)
    Stream-car returns the object in the stream-car field of a stream-pair. It is an error to attempt to evaluate the stream-car of stream-null.
        (stream-car (stream 'a 'b 'c))              => a
        (stream-car stream-null)                    => error
        (stream-car 3)                              => error
    
    (stream-cdr stream) (function)
    Stream-cdr returns the stream in the stream-cdr field of a stream-pair. It is an error to attempt to evaluate the stream-cdr of stream-null.
        (stream-cdr (stream 'a 'b 'c))              => (stream 'b 'c)
        (stream-cdr stream-null)                    => error
        (stream-cdr 3)                              => error
    
    
    (stream-delay expression) (syntax)
    Stream-delay is the essential mechanism for operating on streams, taking an expression and returning a delayed form of the expression that can be asked at some future point to evaluate the expression and return the resulting value. The action of stream-delay is analogous to the action of delay, but it is specific to the stream data type, returning a stream instead of a promise; no corresponding stream-force is required, because each of the stream functions performs the force implicitly.
        (define from0
          (let loop ((x 0))
            (stream-delay
              (stream-cons x (loop (+ x 1))))))
        from0                                       => (stream 0 1 2 3 4 5 6 ...)
    
    (stream object ...) (library function)
    Stream returns a newly allocated finite stream of its arguments, in order.
        (stream 'a (+ 3 4) 'c)                      => (stream 'a 7 'c)
        (stream)                                    => stream-null
    
    (stream-unfoldn generator seed n) (function)
    Stream-unfoldn returns n streams whose contents are produced by successive calls to generator, which takes the current seed as an arguments and returnsn + 1 values:

    (proc seed) -> seed result0 ... resultN

    where resultI indicates how to produce the next element of the Ith result stream:

    (value) value is the next car of this result stream
    #f no new information for this result stream
    () the end of this result stream has been reached
    Note that getting the next element in any particular result stream may require multiple calls to generator.
        (define (take5 s)
          (stream-unfoldn
            (lambda (x)
              (let ((n (car x)) (s (cdr x)))
                (if (zero? n)
                    (values 'dummy '())
                    (values
                      (cons (- n 1) (stream-cdr s))
                      (list (stream-car s))))))
            (cons 5 s)
            1))
        (take5 from0)                              => (stream 0 1 2 3 4)
    
    (stream-map function stream ...) (library function)
    Stream-map creates a newly allocated stream built by applying function elementwise to the elements of the streams. The function must take as many arguments as there are streams and return a single value (not multiple values). The stream returned by stream-map is finite if the given stream is finite, and infinite if the given stream is infinite. If more than one stream is given, stream-map terminates when any of them terminate, or is infinite if all the streams are infinite. The stream elements are evaluated in order.
        (stream-map (lambda (x) (+ x x)) from0)      => (stream 0 2 4 6 8 10 ...)
        (stream-map + (stream 1 2 3) (stream 4 5 6)) => (stream 5 7 9)
        (stream-map (lambda (x) (expt x x))
          (stream 1 2 3 4 5))                        => (stream 1 4 27 256 3125)
    
    (stream-for-each procedure stream ...) (library function)
    Stream-for-each applies procedure elementwise to the elements of the streams, calling the procedure for its side effects rather than for its values. The procedure must take as many arguments as there are streams. The value returned by stream-for-each is unspecified. The stream elements are visited in order.
        (stream-for-each display from0)             => no value, prints 01234 ...
    
    (stream-filter predicate? stream) (library function)
    Stream-filter applies predicate? to each element of stream and creates a newly allocated stream consisting of those elements of the given stream for which predicate? returns a non-#f value. Elements of the output stream are in the same order as they were in the input stream, and are tested by predicate? in order.
        (stream-filter odd? stream-null)            => stream-null
        (take5 (stream-filter odd? from0))          => (stream 1 3 5 7 9)
    

    Implementation

    A reference implementation of streams is shown below. It strongly prefers simplicity and clarity to efficiency, and though a reasonable attempt is made to be safe-for-space, no promises are made. The reference implementation relies on the mechanism for defining record types of SRFI-9, and the functions any and every fromSRFI-1. The stream-error function aborts by calling error as defined in SRFI 23.

    ;;; PROMISES A LA SRFI-45:
    
    ;;; A separate implementation is necessary to
    ;;; have promises that answer #t to stream?
    ;;; This requires lots of complicated type conversions.
    
    (define-record-type s:promise (make-s:promise kind content) s:promise?
      (kind    s:promise-kind    set-s:promise-kind!)
      (content s:promise-content set-s:promise-content!))
    
    (define-record-type box (make-box x) box?
      (x unbox set-box!))
    
    (define-syntax srfi-40:lazy
      (syntax-rules ()
        ((lazy exp)
         (make-box (make-s:promise 'lazy (lambda () exp))))))
    
    (define (srfi-40:eager x)
      (make-stream (make-box (make-s:promise 'eager x))))
    
    (define-syntax srfi-40:delay
      (syntax-rules ()
        ((srfi-40:delay exp) (srfi-40:lazy (srfi-40:eager exp)))))
    
    (define (srfi-40:force promise)
      (let ((content (unbox promise)))
        (case (s:promise-kind content)
          ((eager) (s:promise-content content))
          ((lazy)
           (let* ((promise* (stream-promise ((s:promise-content content))))
                  (content  (unbox promise)))
             (if (not (eqv? 'eager (s:promise-kind content)))
                 (begin
                   (set-s:promise-kind! content (s:promise-kind (unbox promise*)))
                   (set-s:promise-content! content (s:promise-content (unbox promise*)))
                   (set-box! promise* content)))
             (srfi-40:force promise))))))
    
    
    ;;; STREAM -- LIBRARY OF SYNTAX AND FUNCTIONS TO MANIPULATE STREAMS
    
    ;;; A stream is a new data type, disjoint from all other data types, that
    ;;; contains a promise that, when forced, is either nil (a single object
    ;;; distinguishable from all other objects) or consists of an object
    ;;; (the stream element) followed by a stream.  Each stream element is
    ;;; evaluated exactly once, when it is first retrieved (not when it is
    ;;; created); once evaluated its value is saved to be returned by
    ;;; subsequent retrievals without being evaluated again.
    
    ;; STREAM-TYPE -- type of streams
    ;; STREAM? object -- #t if object is a stream, #f otherwise
    (define-record-type stream-type
      (make-stream promise)
      stream?
      (promise stream-promise))
    
    ;;; UTILITY FUNCTIONS
    
    ;; STREAM-ERROR message -- print message then abort execution
    ;  replace this with a call to the native error handler
    ;  if stream-error returns, so will the stream library function that called it
    (define stream-error error)
    
    ;;; STREAM SYNTAX AND FUNCTIONS
    
    ;; STREAM-NULL -- the distinguished nil stream
    (define stream-null (make-stream (srfi-40:delay '())))
    
    ;; STREAM-CONS object stream -- primitive constructor of streams
    (define-syntax stream-cons
      (syntax-rules ()
        ((stream-cons obj strm)
         (make-stream
          (srfi-40:delay
           (if (not (stream? strm))
               (stream-error "attempt to stream-cons onto non-stream")
               (cons obj strm)))))))
    
    ;; STREAM-NULL? object -- #t if object is the null stream, #f otherwise
    (define (stream-null? obj)
      (and (stream? obj) (null? (srfi-40:force (stream-promise obj)))))
    
    ;; STREAM-PAIR? object -- #t if object is a non-null stream, #f otherwise
    (define (stream-pair? obj)
      (and (stream? obj) (not (null? (srfi-40:force (stream-promise obj))))))
    
    ;; STREAM-CAR stream -- first element of stream
    (define (stream-car strm)
      (cond ((not (stream? strm)) (stream-error "attempt to take stream-car of non-stream"))
            ((stream-null? strm)  (stream-error "attempt to take stream-car of null stream"))
            (else (car (srfi-40:force (stream-promise strm))))))
    
    ;; STREAM-CDR stream -- remaining elements of stream after first
    (define (stream-cdr strm)
      (cond ((not (stream? strm)) (stream-error "attempt to take stream-cdr of non-stream"))
            ((stream-null? strm)  (stream-error "attempt to take stream-cdr of null stream"))
            (else (cdr (srfi-40:force (stream-promise strm))))))
    
    ;; STREAM-DELAY object -- the essential stream mechanism
    (define-syntax stream-delay
      (syntax-rules ()
        ((stream-delay expr)
          (make-stream
            (srfi-40:lazy expr)))))
    
    ;; STREAM object ... -- new stream whose elements are object ...
    (define (stream . objs)
      (let loop ((objs objs))
        (stream-delay
          (if (null? objs)
              stream-null
              (stream-cons (car objs) (loop (cdr objs)))))))
    
    ;; STREAM-UNFOLDN generator seed n -- n+1 streams from (generator seed)
    (define (stream-unfoldn gen seed n)
      (define (unfold-result-stream gen seed)
        (let loop ((seed seed))
          (stream-delay
            (call-with-values
              (lambda () (gen seed))
              (lambda (next . results)
                (stream-cons results (loop next)))))))
      (define (result-stream->output-stream result-stream i)
        (stream-delay
          (let ((result (list-ref (stream-car result-stream) i)))
            (cond ((pair? result)
                    (stream-cons (car result)
                                 (result-stream->output-stream
                                   (stream-cdr result-stream) i)))
                  ((not result)
                    (result-stream->output-stream (stream-cdr result-stream) i))
                  ((null? result) stream-null)
                  (else (stream-error "can't happen"))))))
      (define (result-stream->output-streams result-stream n)
        (let loop ((i 0) (outputs '()))
          (if (= i n)
            (apply values (reverse outputs))
            (loop (+ i 1)
                  (cons (result-stream->output-stream result-stream i)
                        outputs)))))
      (result-stream->output-streams (unfold-result-stream gen seed) n))
    
    ;; STREAM-MAP func stream ... -- stream produced by applying func element-wise
    (define (stream-map func . strms)
      (cond ((not (procedure? func)) (stream-error "non-functional argument to stream-map"))
            ((null? strms) (stream-error "no stream arguments to stream-map"))
            ((not (every stream? strms)) (stream-error "non-stream argument to stream-map"))
            (else (let loop ((strms strms))
                    (stream-delay
                      (if (any stream-null? strms)
                          stream-null
                          (stream-cons (apply func (map stream-car strms))
                                       (loop (map stream-cdr strms)))))))))
    
    ;; STREAM-FOR-EACH proc stream ... -- apply proc element-wise for side-effects
    (define (stream-for-each proc . strms)
      (cond ((not (procedure? proc)) (stream-error "non-functional argument to stream-for-each"))
            ((null? strms) (stream-error "no stream arguments to stream-for-each"))
            ((not (every stream? strms)) (stream-error "non-stream argument to stream-for-each"))
            (else (let loop ((strms strms))
                    (if (not (any stream-null? strms))
                        (begin (apply proc (map stream-car strms))
                               (loop (map stream-cdr strms))))))))
    
    ;; STREAM-FILTER pred? stream -- new stream including only items passing pred?
    (define (stream-filter pred? strm)
      (cond ((not (procedure? pred?)) (stream-error "non-functional argument to stream-filter"))
            ((not (stream? strm)) (stream-error "attempt to apply stream-filter to non-stream"))
            (else (stream-unfoldn
                    (lambda (s)
    		  (cond
    		   ((stream-null? s)
    		    (values stream-null '()))
    		   ((pred? (stream-car s))
    		    (values (stream-cdr s) (list (stream-car s))))
    		   (else
    		    (values (stream-cdr s) #f))))
                    strm
                    1))))

    References

    •  Harold Abelson, Gerald Jay Sussman, Julie Sussman: Structure and Interpretation of Computer Programs, 1996, MIT Press.
    •  Lawrence C. Paulson: ML for the Working Programmer, 2nd edition, Cambridge University Press, 1996.
    •  George Springer and Daniel P. Friedman: Scheme and the Art of Programming, MIT Press and McGraw-Hill, 1989.
    •  Philip Wadler, Walid Taha, and David MacQueen: "How to add laziness to a strict language without even being odd", 1998 ACM SIGPLAN Workshop on ML, pp. 24-30. (available here in various formats)
    •  Patrick H. Winston, Berthold K. Horn: Lisp, 3rd edition, Addison Wesley, 1989.
  •  

    Loading mentions Retweet
    Filed under  //  cloud computing   new   pgm   stream computing   technology  
    Comments (0)
    Posted 4 months ago

    Stream Computing FAQ

    What is stream computing?
    Stream computing (or stream processing) refers to a class of compute problems, applications or tasks that can be broken down into parallel, identical operations and run simultaneously on a single processor device. These parallel data streams entering the processor device, computations taking place and the output from the device define stream computing.

    Today, stream computing is primarily the realm of the graphics processor unit (GPU) where the parallel processes used to produce graphics imagery are used instead to perform arithmetic calculations.

    Characteristics of stream computing:

    • Enable new applications on new architectures
    • Parallel problems other than graphics that map well on GPU architecture
    • Transition from fixed function to programmable pipelines
    • Various proof points in research and industry under the name GPGPU

    How does stream computing differ from computation on the CPU?
    Stream computing takes advantage of a SIMD methodology (single instruction, multiple data) whereas a CPU is a modified SISD methodology (single instruction, single data); modifications taking various parallelism techniques into account.

    The benefit of stream computing stems from the highly parallel architecture of the GPU whereby tens to hundreds of parallel operations are performed with each clock cycle whereas the CPU can at best work only a small handful of parallel operations per clock cycle.

    What are AMD's stream computing product features?
    AMD's FireStream™ 9170, our latest generation stream computing GPU, features:

    • 320 stream cores (compute units or ALUs)
    • 2GB on-board GDDR3 memory
    • Double precision floating point support
    • PCIe 2.0 x16 interface

    View AMD FireStream 9170 specifications.

    What are AMD's stream computing product advantages?
    AMD's FireStream 9170 hardware:

    • Only company positioned to offer a unique platform with strengths in accelerated GPU as well as CPU computing
    • Stream computing today leading to fusion tomorrow

    AMD's open systems SDK approach:

    • CTM initiative — Release low level specifications to enable developers and end users to understand the architecture and tuning to maximize performance
    • Deliver high level, multi-targeted compilers through Brook, 3rd parties like RapidMind, and partnerships with universities and industry.
    • Deliver library functions through AMD's ACML, APL, Cobra, and through university partner program.

    View AMD FireStream 9170 specifications.

    When can I get an AMD stream computing product and what does it cost?
    The FireStream 9170, AMD's flagship stream computing platform, is scheduled to be available in Q1 2008 in quantity. Please contact us for a price quote.

    software development kit containing compilers, libraries, performance profiling tools and drivers is available for download. SDK version 1.0 will be available in Q1 2008.

    This SDK is a compilation of open source software and proprietary AMD software put into the open source.

    Included in the first release are compilers, performance profilers, AMD's core math library (ACML) and AMD's compute abstraction layer (CAL) which enables device programming in familiar high-level languages rather than graphics programming specific to the GPU.

    Please read our stream computing whitepaper (PDF 1.1MB) for more information about this SDK.

    How does AMD's stream computing address the IEEE754 standard for double precision floating point computation?
    The IEEE754 standard defines formats for representing single and double-precision floating point numbers as well as some special cases like denorms, infinities and NaNs. It also defines four rounding modes and methods for exception handling.

    When we were preparing to launch our stream computing initiative in 2006, a series of customer interviews was conducted to get input on requirements relative to this standard. They learned that as long as we handled the special cases according to the most common usage, complete IEEE754 compliance wasn't required. AMD's FireStream 9170 implementation should handle a large majority of customers' requirements.

    In the AMD FireStream 9170:

    • Infinities and NaNs are handled as defined by the IEEE754 standard.
    • Rounding is handled using the "round to nearest" mode, which is the mode generally used in most applications.
    • Denormal numbers are flushed to zero. This is a common optimization in implementations where full-speed hardware support is not available, and is adequate for most applications.

    What does AMD's software stack look like?
    AMD has authored a whitepaper (PDF) that discusses our software stack.

    How does the AMD FireStream support Linux?
    AMD is committed to Linux and sees Linux as a major platform for Stream Computing. Recently we have announced an initiative on open source driver for Linux. We are continuing our momentum and we expect that stream computing stack will support Linux over the next calendar year.

    What type of programming model does AMD use for AMD FireStream?
    AMD encourages a pure streaming/SIMD model for AMD FireStream. A few enhancements like data sharing are useful for a small subset of applications. However data sharing in a SIMD environment brings its own challenges and should to be used with utmost care. In fact if used incorrectly performance might actually degrade.

    Regarding specific compiler implementation choices — currently we have enabled Brook with a CAL backend. We are looking at other options as well, including industry standards.

    What happened to AMD's CTM?
    CAL is a natural evolution to CTM — we are building our software stack bottoms up. We provide low-level access and specs as CTM extension to CAL. CAL permits the end user to write portable code. Frequently our developers like to drop down to the next level of detail for further tuning and profiling. CAL provides this level of access.

    Will the AMD FireStream SDK work on previous generation hardware?
    To run the CAL/Brook+ SDK, you need a platform based on the AMD R600 GPU or later. R600 and newer GPUs are found with ATI Radeon™ HD2400, HD2600, HD2900 and HD3800 graphics board.

    Which applications are best suited to Stream Computing?
    Applications best suited to stream computing possess two fundamental characteristics:

    1. A high degree of arithmetic computation per system memory fetch
    2. Computational independence — arithmetic occurs on each processing unit without needing to be checked or verified by or with arithmetic occurring on any other processing unit.

    Examples include:

    • Engineering — fluid dynamics
    • Mathematics — linear equations, matrix calculations
    • Simulations — Monte Carlo, molecular modeling, etc.
    • Financial — options pricing
    • Biological — protein structure calculations
    • Imaging — medical image processing

    If Stream processors are really GPUs, will I need to learn graphics programming to properly implement my application?
    No. AMD along with the open source community are working to mask the GPU's graphics programming heritage. This is being accomplished by our release of Brook+, the open source Brook compiler plus AMD enhancements geared directly at non-graphics stream computing, and AMD's CAL — Compute Abstraction Layer. CAL provides high-level language access to the various parts of the GPU as needed.

    Developers are thus able to write directly to the GPU without needing to learn graphics-specific programming languages. CAL provides direct communication to the device.

    Will future stream computing architectures force me to rewrite my applications?
    Implementing a new algorithm or application in a stream computing environment will require the use of various stream-specific techniques. These techniques and tools are all available in the AMD FireStream SDK described above.

    Existing applications that currently use only the CPU for computation will require recompiling to take advantage of the capabilities of the stream processor.

    We anticipate most applications running in a stream computing environment in the near term will be applications written from scratch with the intent of implementing a stream computing platform.

    Over time as applications undergo typical rewrites and recompiles, those applications naturally suited to the stream computing environment will migrate to this environment along with the necessary recoding and recompiling tasks.

    Is stream computing a return to the old co-processor days?
    In many ways stream computing does resemble the days when vector co-processors handled substantial mathematical tasks. The benefit then as now is the remarkable performance boost gained through implementing these specialized components.

    We fully anticipate technological advancements as well as programming techniques to pull these co-processors closer to the CPU over time until, as with earlier co-processors, they disappear into the CPU itself.

    AMD's competitors offer similar but non-standardized products. Should I wait on product standardization before exploring Stream Computing?
    AMD is focused on providing the tools necessary to help our customers succeed with our AMD FireStream products, and we believe the open systems approach is a critical component of this philosophy. Open systems enables AMD along with partners and 3rd party vendors to collaborate closely when developing highly integrated solutions as well as work independently when targeting a niche solution.

    AMD's open systems philosophy includes:

    • Open IL and ISA specifications to ensure developers can optimize system performance
    • Support for AMD Brook+ along with other 3rd party high-level tools to provide a choice of familiar development environments
    • Open source Linux drivers and AMD-enhanced Brook+ enabling developers to modify and retarget tools as needed
    • AMD partnership opportunities with system vendors and integrators to deliver customer-focused solutions

    Who can I contact at AMD for more information?
    Contact us with general questions about AMD's stream computing initiative, products, sales and training.

    Contact us with technical questions about FireStream hardware, software or developer issues.

    AMD Compute Abstraction Layer (CAL) FAQ

    How do I get started with AMD CAL SDK?
    We have assembled a number of documents to help guide you through the setup and early use of CAL. Please read these before getting started:

    We have also authored a programmer's guide which is included in the SDK download.

    Note that the three CAL files are also included in the SDK. We have posted them here as well for your reference prior to installing CAL.

    Why does the integrated installer (setup.exe) behave badly?
    The integrated installer is designed to invoke the CAL and BROOK+ installers in that order. Most of the installation logic is present in each individual MSI.

    If you have problems with this installer, please remove any previous versions of CAL/BROOK+ using Add/Remove programs in Control Panel and try again.

    Does the Repair/Modify option update my previous installation of CAL/BROOK+?
    No, you would need to completely remove the previous version of CAL/BROOK+. The Repair/Modify option only repairs the current version of CAL/BROOK+.

    What is CALROOT and where is it set and used?
    CALROOT is set as the path to the CAL SDK during installation. It is defined in the current user's Environment Variables. Other users on the system have to define CALROOT in their environment or in the system environment.

    The Visual Studio project files for the samples use CALROOT to locate the CAL headers and libraries. Some sample projects also use CALROOT to load themselves. You would not need CALROOT unless you wish to build the samples.

    Brook+ FAQ

    How do I get started with Brook+?
    Brook+ requires the following be installed or available to work with AMD FireStream technology:

    • Visual Studio (for Windows developers) or GCC (for Linux developers) installed and all environment variables correctly set up
    • Cygwin (for Windows) — must appear later in the PATH variable than the Visual Studio tools
    • CAL SDK installed from the same source as you obtained the source tree from
    • CALROOT environment variable set

    To build the compiler and runtime, enter the "platform" directory and type "make". This generates and fills the "sdk" directory.

    To build the samples, first build the sdk as above, then enter the "samples" directory and type "make".

    Where can I get CAL support?
    Information was shipped in the installer.

    What graphics driver does Brook+ require?
    Brook+ has no direct dependency on the graphics driver. CAL working correctly with a given driver should result in Brook+ working correctly.

    How is BROOKROOT used?
    The makefiles need CALROOT defining. BROOKROOT is not used by the makefile system.

     

    Loading mentions Retweet
    Filed under  //  HIVE   IBM   new   pgm   stream computing   technology  
    Comments (0)
    Posted 4 months ago

    Apps, Apps, and More Apps! Introducing the Windows Web App Gallery - Including Drupal, WordPress, DotNetNuke, and More!

    article posted by

    Lauren Cooney's Reality Check

     

    What We’re Announcing Today:

    -       A kick-ass new website: www.microsoft.com/web - which includes everything and anything you could possibly want to know (and probably more) about Microsoft’s web products.

    -       An updated version of the Microsoft Web Platform Installer– which includes PHP!

    -       The Windows Web Application Gallery– browse popular open source .NET and PHP web applications to easily install on top of Windows, or else build your own applications into the gallery – and reach millions of customers, developers, and communities worldwide!

     

    For those of you who want a bit more info – and I know that some of you do -

    Here’s the back story:

    Last June a few of us from Redmond took a trip down to San Francisco to figure out next steps for the direction that we wanted to move with Microsoft's web products. The developer ecosystem was changing, and we had great products and great customers, but we wanted to do more for our customers, the communities out there that wanted to use Windows - and, we wanted to figure out different ways that we could help developers be successful.

    I had just come onboard as the lead for the Web Platform & Standards team, and between me, Bill Staples (General Manager of Web Products), Brian Goldfarb (Director of UX/Web), and a few others we put our heads together and came up with a few principles that we really wanted our web platform products and solutions to embody: (1) Simplicity, (2), Interoperability, and (3) Integration.

    Today as we formally announce some of the pieces that extend on our web platform vision, I am happy to say that each component that we are announcing today deliver on each of these critical core values that are so important for developers, for communities out there, and for our customers.

    So what are we announcing as part of the Microsoft Web Platform today? (other than the brand-spanking new website we have)

     

    (1) The Microsoft Web Platform Installer 2.0 Beta.(WebPI)

    What does this do? It installs all the free Microsoft web products onto your Windows Server box, or your hosted server.

    Why do I need this?                                                        

    Well, first of all, this version of the WebPI  installs the community version of PHP. Additionally, instead of going to several different websites to download and install Microsoft's web products, you can now seamlessly and quickly install them from one website - and you can update them from this website as well. This is the simplicity we have been aiming for - one website, one download, and simple updates to the best products for building web solutions.

    Why did Microsoft include the Community Version of PHP inside of the Web Platform Installer?

    Microsoft is committed to providing developers and communities with the best solutions for building Web applications. Many popular applications are built using PHP, and Microsoft wants to ensure that its customers, community members, and developers are able to use these solutions on top of the Microsoft Web Platform – and including PHP inside of the Web PI simplifies this for Web developers. This is a critical piece of the Microsoft Web Platform strategy – which built to work with customers, communities, and developers - in mind.

    What products does the WebPI include?

    ·         Internet Information Services (IIS) 5.1 on Windows XP SP3

    ·         IIS 6.0 on Windows Server 2003 SP2

    ·         IIS 7.0 on Windows Vista SP1 and Windows Server 2008

    ·         SQL Server 2008 Express,

    ·         .NET Framework 3.5 SP1

    ·         Visual Web Developer 2008 Express Edition

    ·         IIS Extensions including:

    o   IIS 7 Media Services 3.0

    o   IIS7 Administration Pack

    o   Database Manager for IIS7

    o   WebDav 7.5

    o   FTP 7.5

    o   FastCGI for PHP support on IIS6

    o   URL Rewriter

    o   IIS 7 Application Routing

    o   Web Deployment Tool for IIS

    ·         ASP.NET and features such as ASP.NET MVC

    ·         Silverlight Tools for Visual Studio

    ·         The Community Version of PHP v5.2.9-1

     

     

    (2) The Windows Web Application Gallery

    What is the Windows Web Application Gallery?

    -       The Windows Web Application Gallery is a community hub of the most popular Open Source and community Web applications that run on Windows.

    -       It provides a simple streamlined way for users to explore, discover, and install ASP.NET, PHP, and other types of Web applications and solutions on the Windows Platform.

    -       It also provides a simple way for developers to offer their applications to the millions of users worldwide.

    What applications are currently included in the Windows Web App Gallery?

    Current applications include: Acquia Drupal, DotNetNuke, WordPress, dasBlog, Gallery, SilverStripe, BlogEngine.NET, SubText, Umbraco, and ScrewTurn Wiki.

     

    What are the benefits of using the Windows Web App Gallery?

    A Great User Experience

    The Windows Web Application Gallery makes it easy to explore, discover and install popular community ASP.NET and PHP applications for the Windows Platform. Discover and install web applications through the Microsoft.com website, the Microsoft Web PI, IIS 7.0 Manager, and participating hosting control panels.

    A Strong Community Ecosystem

    The Windows Web Application Gallery creates a social hub for connecting users to the right Web solutions. Make informed decisions and help others make decisions based on community ratings and reviews. Developers get access to a wealth of feedback helping them pinpoint ways to improve their web application. In addition, with numerous community and customized applications, developers no longer have to build their solutions from scratch; there are plentiful applications that solve real-world problems, and can be downloaded and installed, customized, and ready to go – saving both money and time for developers.

    Easy Distribution & Amazing Market Opportunities

    The Windows Web Application Gallery provides developers a simple way to offer their Web applications to millions of Windows users worldwide. By adding an application to the Windows Web Application Gallery that you package and we publish, you will gain access to millions of developers and end-users that are looking to discover solutions that will make them successful.

     

    So I can build applications to the Windows Web Application Gallery?

    Yes! You can - and by adding Web Application Gallery integration to your existing ZIP package, users can access your app inside the gallery - and Microsoft will help distribute and market it to millions of Windows developers worldwide. It's an easy way to distribute your application, promote your solution, or gain fame in the Windows community - oh - and help others be successful building web solutions.

    I have to give kudos here to an amazing engineering team, a rockstar marketing team, and the superb website teams that we had working on this. Tremendous work has been done - and we've got lots more to come.

     

    Loading mentions Retweet
    Filed under  //  microsoft   pgm   social networking   technology  
    Comments (0)
    Posted 4 months ago